Skip to content

Commit

Permalink
fix(core): wrap errors with no linter rules
Browse files Browse the repository at this point in the history
  • Loading branch information
ayuhito committed Mar 4, 2024
1 parent 71e4501 commit c734118
Show file tree
Hide file tree
Showing 19 changed files with 166 additions and 138 deletions.
20 changes: 13 additions & 7 deletions core/.golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ linters-settings:
# The maximal code complexity to report.
# Default: 10
max-complexity: 30
# The maximal average package complexity.
# If it's higher than 0.0 (float) the check is enabled
# Default: 0.0
package-average: 10.0

errcheck:
# Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
Expand Down Expand Up @@ -104,6 +100,9 @@ linters-settings:
# Otherwise, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.
# Default: false
all: true
wrapcheck:
ignorePackageGlobs:
- services

linters:
disable-all: true
Expand All @@ -121,6 +120,8 @@ linters:
- asciicheck # checks that your code does not contain non-ASCII identifiers
- bidichk # checks for dangerous unicode character sequences
- bodyclose # checks whether HTTP response body is closed successfully
- containedctx # checks for context.Context contained in a struct
- contextcheck # checks for common mistakes using context
- cyclop # checks function and package cyclomatic complexity
# - dupl # tool for code clone detection
- durationcheck # checks for two durations multiplied together
Expand All @@ -131,13 +132,15 @@ linters:
- exportloopref # checks for pointers to enclosing loop variables
- forbidigo # forbids identifiers
# - funlen # tool for detection of long functions # disabled because of routers and handlers in one function
- gci # controls golang package import order and makes it always deterministic
- gocheckcompilerdirectives # validates go compiler directive comments (//go:)
- gochecknoglobals # checks that no global variables exist
- gochecknoinits # checks that no init functions are present in Go code
# - gocognit # computes and checks the cognitive complexity of functions
- goconst # finds repeated strings that could be replaced by a constant
- gocritic # provides diagnostics that check for bugs, performance and style issues
- gocyclo # computes and checks the cyclomatic complexity of functions
- gofumpt # checks if the code is formatted with gofumpt
- godot # checks if comments end in a period
- goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt
- gomnd # detects magic numbers
Expand All @@ -157,24 +160,27 @@ linters:
- nolintlint # reports ill-formed or insufficient nolint directives
- nonamedreturns # reports all named returns
- nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL
- prealloc # finds slice declarations that could potentially be preallocated
- predeclared # finds code that shadows one of Go's predeclared identifiers
- promlinter # checks Prometheus metrics naming via promlint
- reassign # checks that package variables are not reassigned
- revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint
- rowserrcheck # checks whether Err of rows is checked successfully
- sqlclosecheck # checks that sql.Rows and sql.Stmt are closed
- sloglint # ensure consistent logging style
# - sqlclosecheck # Disabled until https://github.com/ryanrolds/sqlclosecheck/issues/35 is resolved
- stylecheck # is a replacement for golint
- tenv # detects using os.Setenv instead of t.Setenv since Go1.17
- testableexamples # checks if examples are testable (have an expected output)
- testifylint # checks for common mistakes using the testify package
- testpackage # makes you use a separate _test package
- thelper # checks that the helper functions are not used in the test
- tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes
- unconvert # removes unnecessary type conversions
- unparam # reports unused function parameters
- usestdlibvars # detects the possibility to use variables/constants from the Go standard library
- wastedassign # finds wasted assignment statements
- whitespace # detects leading and trailing whitespace
- gci # controls golang package import order and makes it always deterministic
- godox # detects FIXME, TODO and other comment keywords
- wrapcheck # checks that the code does not use the wrapping of errors

issues:
# Maximum count of issues with the same text.
Expand Down
7 changes: 4 additions & 3 deletions core/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"time"

"github.com/caarlos0/env/v10"
"github.com/go-faster/errors"
)

type ServerConfig struct {
Expand Down Expand Up @@ -59,7 +60,7 @@ func NewServerConfig() (*ServerConfig, error) {

// Load config from environment variables.
if err := env.Parse(config); err != nil {
return nil, err
return nil, errors.Wrap(err, "config")
}

return config, nil
Expand All @@ -73,7 +74,7 @@ func NewAppDBConfig() (*AppDBConfig, error) {

// Load config from environment variables.
if err := env.Parse(config); err != nil {
return nil, err
return nil, errors.Wrap(err, "config")
}

return config, nil
Expand All @@ -87,7 +88,7 @@ func NewAnalyticsDBConfig() (*AnalyticsDBConfig, error) {

// Load config from environment variables.
if err := env.Parse(config); err != nil {
return nil, err
return nil, errors.Wrap(err, "config")
}

return config, nil
Expand Down
30 changes: 17 additions & 13 deletions core/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strconv"
"syscall"

"github.com/go-faster/errors"
generate "github.com/medama-io/medama"
"github.com/medama-io/medama/api"
"github.com/medama-io/medama/db/duckdb"
Expand All @@ -33,17 +34,17 @@ type StartCommand struct {
func NewStartCommand() (*StartCommand, error) {
serverConfig, err := NewServerConfig()
if err != nil {
return nil, err
return nil, errors.Wrap(err, "failed to create server config")
}

appConfig, err := NewAppDBConfig()
if err != nil {
return nil, err
return nil, errors.Wrap(err, "failed to create app db config")
}

analyticsConfig, err := NewAnalyticsDBConfig()
if err != nil {
return nil, err
return nil, errors.Wrap(err, "failed to create analytics db config")
}

return &StartCommand{
Expand All @@ -60,7 +61,12 @@ func (s *StartCommand) ParseFlags(args []string) error {
fs.Int64Var(&s.Server.Port, "port", DefaultPort, "Port to listen on")

// Parse flags
return fs.Parse(args)
err := fs.Parse(args)
if err != nil {
return errors.Wrap(err, "failed to parse flags")
}

return nil
}

// Run executes the start command.
Expand All @@ -71,36 +77,34 @@ func (s *StartCommand) Run(ctx context.Context) error {
// Setup database
sqlite, err := sqlite.NewClient(s.AppDB.Host)
if err != nil {
return err
return errors.Wrap(err, "failed to create sqlite client")
}

duckdb, err := duckdb.NewClient(s.AnalyticsDB.Host)
if err != nil {
return err
return errors.Wrap(err, "failed to create duckdb client")
}

// Run migrations
m := migrations.NewMigrationsService(ctx, sqlite, duckdb)
if m == nil {
slog.Error("Could not create migrations service")
return err
return errors.New("could not create migrations service")
}
err = m.AutoMigrate(ctx)
if err != nil {
slog.Error("Could not run migrations", "error", err)
return err
return errors.Wrap(err, "could not run migrations")
}

// Setup auth service
auth, err := util.NewAuthService(ctx)
if err != nil {
return err
return errors.Wrap(err, "failed to create auth service")
}

// Setup handlers
service, err := services.NewService(auth, sqlite, duckdb)
if err != nil {
return err
return errors.Wrap(err, "failed to create handlers")
}

authMiddleware := middlewares.NewAuthHandler(auth)
Expand All @@ -116,7 +120,7 @@ func (s *StartCommand) Run(ctx context.Context) error {
api.WithNotFound(middlewares.NotFound()),
)
if err != nil {
return err
return errors.Wrap(err, "failed to create server")
}

// We need to add additional static routes for the web app.
Expand Down
7 changes: 4 additions & 3 deletions core/db/duckdb/client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package duckdb

import (
"github.com/go-faster/errors"
"github.com/jmoiron/sqlx"
"github.com/medama-io/medama/db"
)
Expand All @@ -18,21 +19,21 @@ var (
func NewClient(host string) (*Client, error) {
db, err := sqlx.Connect("duckdb", host)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "duckdb")
}

// Enable ICU extension
_, err = db.Exec(`--sql
INSTALL icu;`)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "duckdb")
}

// Load ICU extension
_, err = db.Exec(`--sql
LOAD icu;`)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "duckdb")
}

return &Client{
Expand Down
5 changes: 3 additions & 2 deletions core/db/duckdb/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package duckdb
import (
"context"

"github.com/go-faster/errors"
"github.com/medama-io/medama/model"
)

Expand All @@ -14,7 +15,7 @@ func (c *Client) AddPageView(ctx context.Context, event *model.PageViewHit) erro

_, err := c.DB.ExecContext(ctx, exec, event.BID, event.Hostname, event.Pathname, event.IsUniqueUser, event.IsUniquePage, event.Referrer, event.CountryCode, event.Language, event.BrowserName, event.OS, event.DeviceType, event.UTMSource, event.UTMMedium, event.UTMCampaign)
if err != nil {
return err
return errors.Wrap(err, "db")
}

return nil
Expand All @@ -26,7 +27,7 @@ func (c *Client) UpdatePageView(ctx context.Context, event *model.PageViewDurati
UPDATE views SET bid = NULL, duration_ms = ? WHERE bid = ?`,
event.DurationMs, event.BID)
if err != nil {
return err
return errors.Wrap(err, "db")
}

return nil
Expand Down
12 changes: 7 additions & 5 deletions core/db/duckdb/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,31 @@ import (
"github.com/medama-io/medama/migrations"
"github.com/medama-io/medama/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func SetupDatabase(t *testing.T) (*assert.Assertions, context.Context, *duckdb.Client) {
t.Helper()
assert := assert.New(t)
require := require.New(t)
ctx := context.Background()
// Disable logging
log.SetOutput(io.Discard)

// Generate new memory db per test
client, err := sqlite.NewClient(fmt.Sprintf("file:%s?mode=memory&cache=shared", t.Name()))
assert.NoError(err)
require.NoError(err)
assert.NotNil(client)

// In memory duckdb client
duckdbClient, err := duckdb.NewClient("")
assert.NoError(err)
require.NoError(err)
assert.NotNil(duckdbClient)

// Run migrations
m := migrations.NewMigrationsService(ctx, client, duckdbClient)
err = m.AutoMigrate(ctx)
assert.NoError(err)
require.NoError(err)

// Create test user
userCreate := model.NewUser(
Expand All @@ -48,7 +50,7 @@ func SetupDatabase(t *testing.T) (*assert.Assertions, context.Context, *duckdb.C
2, // dateUpdated
)
err = client.CreateUser(ctx, userCreate)
assert.NoError(err)
require.NoError(err)

// Create test website
websiteCreate := model.NewWebsite(
Expand All @@ -59,7 +61,7 @@ func SetupDatabase(t *testing.T) (*assert.Assertions, context.Context, *duckdb.C
2, // dateUpdated
)
err = client.CreateWebsite(ctx, websiteCreate)
assert.NoError(err)
require.NoError(err)

return assert, ctx, duckdbClient
}
Loading

0 comments on commit c734118

Please sign in to comment.