fix: resolve all golangci-lint v2 failures
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Production fixes:
- cmd/server/main.go: refactor to run() helper to eliminate exitAfterDefer
(os.Exit in main() no longer bypasses deferred s.Close)
- internal/cast/client.go: use _ = resp.Body.Close() (errcheck)
- internal/ghl/api.go: wrap both defers as func(){ _ = resp.Body.Close() }()
Test fixes:
- internal/cast/client_test.go: replace err.(*CastAPIError) type assertions
with errors.As (errorlint)
Config:
- .golangci.yml: use explicit path regex .*_test\\.go and add errorlint
to test-file exclusions
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
8f2080203d
commit
6a853f6566
@ -18,7 +18,8 @@ linters:
|
|||||||
issues:
|
issues:
|
||||||
exclusions:
|
exclusions:
|
||||||
rules:
|
rules:
|
||||||
- path: _test\.go
|
- path: ".*_test\\.go"
|
||||||
linters:
|
linters:
|
||||||
- errcheck
|
- errcheck
|
||||||
- gocritic
|
- gocritic
|
||||||
|
- errorlint
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -20,21 +21,25 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelInfo})))
|
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelInfo})))
|
||||||
|
if err := run(); err != nil {
|
||||||
|
slog.Error("fatal error", "err", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func run() error {
|
||||||
cfg, err := config.Load()
|
cfg, err := config.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("config error", "err", err)
|
return fmt.Errorf("config: %w", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
s, err := store.NewStore(ctx, cfg.MongoURI)
|
s, err := store.NewStore(ctx, cfg.MongoURI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("failed to connect to mongodb", "err", err)
|
return fmt.Errorf("mongodb: %w", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
defer s.Close(ctx)
|
defer func() { _ = s.Close(ctx) }()
|
||||||
|
|
||||||
castClient := cast.NewClient(cfg.CastAPIURL, cfg.CastAPIKey, cfg.CastSenderID)
|
castClient := cast.NewClient(cfg.CastAPIURL, cfg.CastAPIKey, cfg.CastSenderID)
|
||||||
ghlAPI := ghl.NewAPIClient()
|
ghlAPI := ghl.NewAPIClient()
|
||||||
@ -42,8 +47,7 @@ func main() {
|
|||||||
|
|
||||||
webhookHandler, err := ghl.NewWebhookHandler(cfg.GHLWebhookPublicKey, castClient, ghlAPI, oauthHandler, s)
|
webhookHandler, err := ghl.NewWebhookHandler(cfg.GHLWebhookPublicKey, castClient, ghlAPI, oauthHandler, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("failed to initialize webhook handler", "err", err)
|
return fmt.Errorf("webhook handler: %w", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
@ -77,9 +81,9 @@ func main() {
|
|||||||
|
|
||||||
slog.Info("cast-ghl-provider started", "port", cfg.Port, "base_url", cfg.BaseURL)
|
slog.Info("cast-ghl-provider started", "port", cfg.Port, "base_url", cfg.BaseURL)
|
||||||
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
||||||
slog.Error("server error", "err", err)
|
return fmt.Errorf("server: %w", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func healthCheck(w http.ResponseWriter, r *http.Request) {
|
func healthCheck(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
@ -60,7 +60,7 @@ func (c *Client) SendSMS(ctx context.Context, to, message string) (*SendResponse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
slog.Warn("cast api rate limited, retrying", "attempt", attempt+1, "wait", wait)
|
slog.Warn("cast api rate limited, retrying", "attempt", attempt+1, "wait", wait)
|
||||||
resp.Body.Close()
|
_ = resp.Body.Close()
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
@ -70,7 +70,7 @@ func (c *Client) SendSMS(ctx context.Context, to, message string) (*SendResponse
|
|||||||
}
|
}
|
||||||
|
|
||||||
data, err := io.ReadAll(resp.Body)
|
data, err := io.ReadAll(resp.Body)
|
||||||
resp.Body.Close()
|
_ = resp.Body.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package cast
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@ -52,8 +53,8 @@ func TestSendSMS_APIError(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error, got nil")
|
t.Fatal("expected error, got nil")
|
||||||
}
|
}
|
||||||
castErr, ok := err.(*CastAPIError)
|
var castErr *CastAPIError
|
||||||
if !ok {
|
if !errors.As(err, &castErr) {
|
||||||
t.Fatalf("expected CastAPIError, got %T", err)
|
t.Fatalf("expected CastAPIError, got %T", err)
|
||||||
}
|
}
|
||||||
if castErr.StatusCode != http.StatusPaymentRequired {
|
if castErr.StatusCode != http.StatusPaymentRequired {
|
||||||
@ -73,8 +74,8 @@ func TestSendSMS_SuccessFalseInBody(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error, got nil")
|
t.Fatal("expected error, got nil")
|
||||||
}
|
}
|
||||||
castErr, ok := err.(*CastAPIError)
|
var castErr *CastAPIError
|
||||||
if !ok {
|
if !errors.As(err, &castErr) {
|
||||||
t.Fatalf("expected CastAPIError, got %T", err)
|
t.Fatalf("expected CastAPIError, got %T", err)
|
||||||
}
|
}
|
||||||
if castErr.APIError != "invalid number" {
|
if castErr.APIError != "invalid number" {
|
||||||
@ -133,8 +134,8 @@ func TestSendSMS_Unauthorized(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error for 401, got nil")
|
t.Fatal("expected error for 401, got nil")
|
||||||
}
|
}
|
||||||
castErr, ok := err.(*CastAPIError)
|
var castErr *CastAPIError
|
||||||
if !ok {
|
if !errors.As(err, &castErr) {
|
||||||
t.Fatalf("expected CastAPIError, got %T: %v", err, err)
|
t.Fatalf("expected CastAPIError, got %T: %v", err, err)
|
||||||
}
|
}
|
||||||
if castErr.StatusCode != http.StatusUnauthorized {
|
if castErr.StatusCode != http.StatusUnauthorized {
|
||||||
|
|||||||
@ -44,7 +44,7 @@ func (c *APIClient) UpdateMessageStatus(ctx context.Context, accessToken, messag
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer func() { _ = resp.Body.Close() }()
|
||||||
respBody, err := io.ReadAll(resp.Body)
|
respBody, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ghl update status: failed to read response body: %w", err)
|
return fmt.Errorf("ghl update status: failed to read response body: %w", err)
|
||||||
@ -75,7 +75,7 @@ func (c *APIClient) PostInboundMessage(ctx context.Context, accessToken string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer func() { _ = resp.Body.Close() }()
|
||||||
respBody, err := io.ReadAll(resp.Body)
|
respBody, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user