diff --git a/cleoc/cleoc/config.go b/cleoc/cleoc/config.go index edee522e..5fe183fa 100644 --- a/cleoc/cleoc/config.go +++ b/cleoc/cleoc/config.go @@ -1,11 +1,12 @@ package cleoc import ( - "fmt" "strings" "github.com/adrg/xdg" "github.com/spf13/viper" + + "github.com/cleodora-forecasting/cleodora/cleoutils/errors" ) const DefaultConfigFileName = "cleoc" @@ -37,7 +38,7 @@ func (c *Config) LoadWithViper(v *viper.Viper) error { // Note that ConfigFileNotFoundError is not returned when // explicitly specifying a config path (--config), which should // (and does) cause an error if it doesn't exist. - return fmt.Errorf("error reading config file: %w", err) + return errors.Newf("error reading config file: %w", err) } } } diff --git a/cleoc/cleoc/forecast.go b/cleoc/cleoc/forecast.go index 10544f73..e3caf9e5 100644 --- a/cleoc/cleoc/forecast.go +++ b/cleoc/cleoc/forecast.go @@ -2,7 +2,6 @@ package cleoc import ( "context" - "errors" "fmt" "net/http" "time" @@ -11,6 +10,7 @@ import ( "github.com/hashicorp/go-multierror" "github.com/cleodora-forecasting/cleodora/cleoc/gqclient" + "github.com/cleodora-forecasting/cleodora/cleoutils/errors" ) // AddForecast creates a new forecast. @@ -18,13 +18,13 @@ import ( func (a *App) AddForecast(opts AddForecastOptions) error { resolvesT, err := time.Parse(time.RFC3339, opts.Resolves) if err != nil { - return fmt.Errorf("could not parse 'resolves': %w", err) + return errors.Newf("could not parse 'resolves': %w", err) } var closesT *time.Time if opts.Closes != "" { parsedTime, err := time.Parse(time.RFC3339, opts.Closes) if err != nil { - return fmt.Errorf("could not parse 'closes': %w", err) + return errors.Newf("could not parse 'closes': %w", err) } closesT = &parsedTime } @@ -42,7 +42,7 @@ func (a *App) AddForecast(opts AddForecastOptions) error { reqProbabilities, err := parseProbabilities(opts.Probabilities) if err != nil { - return fmt.Errorf("error parsing probabilities: %w", err) + return errors.Newf("error parsing probabilities: %w", err) } estimate := gqclient.NewEstimate{ @@ -51,7 +51,7 @@ func (a *App) AddForecast(opts AddForecastOptions) error { } resp, err := gqclient.CreateForecast(ctx, client, forecast, estimate) if err != nil { - return fmt.Errorf("error calling the API: %w", err) + return errors.Newf("error calling the API: %w", err) } _, err = fmt.Fprint(a.Out, resp.CreateForecast.Id+"\n") if err != nil { @@ -141,7 +141,7 @@ func (opts *AddForecastOptions) Validate() error { if sumProbabilities != 100 { validationErr = multierror.Append( validationErr, - fmt.Errorf( + errors.Newf( "all probabilities must add up to 100 (here only %v)", sumProbabilities, ), diff --git a/cleosrv/cleosrv/cleosrv.go b/cleosrv/cleosrv/cleosrv.go index 0a125305..b2662fbc 100644 --- a/cleosrv/cleosrv/cleosrv.go +++ b/cleosrv/cleosrv/cleosrv.go @@ -18,6 +18,7 @@ import ( "github.com/cleodora-forecasting/cleodora/cleosrv/graph" "github.com/cleodora-forecasting/cleodora/cleosrv/graph/generated" "github.com/cleodora-forecasting/cleodora/cleoutils" + "github.com/cleodora-forecasting/cleodora/cleoutils/errors" ) type App struct { @@ -56,7 +57,7 @@ Listening on: %s err := os.MkdirAll(filepath.Dir(a.Config.Database), 0770) if err != nil { - return fmt.Errorf("error making directories for database %v: %w", a.Config.Database, err) + return errors.Newf("error making directories for database %v: %w", a.Config.Database, err) } router := chi.NewRouter() @@ -103,7 +104,7 @@ func (a *App) InitDB() (*gorm.DB, error) { err = migrateDB(db) if err != nil { - return nil, fmt.Errorf("migrating data: %w", err) + return nil, errors.Newf("migrating data: %w", err) } return db, nil @@ -121,7 +122,7 @@ func migrateDB(db *gorm.DB) error { return tx.Migrator().AutoMigrate(&Migrations{}) }) if err != nil { - return fmt.Errorf("auto migrating 'migrations' table: %w", err) + return errors.Newf("auto migrating 'migrations' table: %w", err) } // If the DB is completely new then we just insert all migrations as 'done' // i.e. they are not really executed because the createDb() function is @@ -130,7 +131,7 @@ func migrateDB(db *gorm.DB) error { err := db.Transaction(func(tx *gorm.DB) error { err := createDb(tx) if err != nil { - return fmt.Errorf("creating tables: %w", err) + return errors.Newf("creating tables: %w", err) } // save all migrations as done in the DB, without executing the // functions. @@ -146,7 +147,7 @@ func migrateDB(db *gorm.DB) error { } ret := tx.Create(mEntries) if ret.Error != nil { - return fmt.Errorf("storing migrations as done in DB: %w", ret.Error) + return errors.Newf("storing migrations as done in DB: %w", ret.Error) } return nil }) @@ -157,7 +158,7 @@ func migrateDB(db *gorm.DB) error { var count int64 ret := db.Model(&Migrations{}).Where("id = ?", m.ID).Count(&count) if ret.Error != nil { - return fmt.Errorf("selecting migration %v: %w", m.ID, ret.Error) + return errors.Newf("selecting migration %v: %w", m.ID, ret.Error) } if count == 1 { continue // migration already ran in the past @@ -167,7 +168,7 @@ func migrateDB(db *gorm.DB) error { if m.Up != nil { err = m.Up(tx) if err != nil { - return fmt.Errorf("running %v: %w", m.ID, err) + return errors.Newf("running %v: %w", m.ID, err) } } ret = tx.Create(Migrations{ @@ -175,7 +176,7 @@ func migrateDB(db *gorm.DB) error { Applied: time.Now().UTC(), }) if ret.Error != nil { - return fmt.Errorf("saving migration %v: %w", m.ID, ret.Error) + return errors.Newf("saving migration %v: %w", m.ID, ret.Error) } fmt.Printf("Finished DB migration '%v'\n", m.ID) return nil @@ -225,7 +226,7 @@ var dbMigrations = []dbMigration{ var forecasts []Forecast ret := db.Find(&forecasts) if ret.Error != nil { - return fmt.Errorf("getting forecasts: %w", ret.Error) + return errors.Newf("getting forecasts: %w", ret.Error) } for _, f := range forecasts { f.Created = f.Created.UTC() @@ -252,7 +253,7 @@ var dbMigrations = []dbMigration{ } ret = db.Save(f) if ret.Error != nil { - return fmt.Errorf("saving %v: %w", f.ID, ret.Error) + return errors.Newf("saving %v: %w", f.ID, ret.Error) } } return nil @@ -268,14 +269,14 @@ var dbMigrations = []dbMigration{ var estimates []Estimate ret := db.Find(&estimates) if ret.Error != nil { - return fmt.Errorf("getting estimates: %w", ret.Error) + return errors.Newf("getting estimates: %w", ret.Error) } for _, e := range estimates { e.Created = e.Created.UTC() e.CreatedAt = e.CreatedAt.UTC() ret = db.Save(e) if ret.Error != nil { - return fmt.Errorf("saving %v: %w", e.ID, ret.Error) + return errors.Newf("saving %v: %w", e.ID, ret.Error) } } return nil @@ -290,13 +291,13 @@ var dbMigrations = []dbMigration{ var outcomes []Outcome ret := db.Find(&outcomes) if ret.Error != nil { - return fmt.Errorf("getting outcomes: %w", ret.Error) + return errors.Newf("getting outcomes: %w", ret.Error) } for _, o := range outcomes { o.CreatedAt = o.CreatedAt.UTC() ret = db.Save(o) if ret.Error != nil { - return fmt.Errorf("saving %v: %w", o.ID, ret.Error) + return errors.Newf("saving %v: %w", o.ID, ret.Error) } } return nil @@ -311,13 +312,13 @@ var dbMigrations = []dbMigration{ var probabilities []Probability ret := db.Find(&probabilities) if ret.Error != nil { - return fmt.Errorf("getting probabilities: %w", ret.Error) + return errors.Newf("getting probabilities: %w", ret.Error) } for _, p := range probabilities { p.CreatedAt = p.CreatedAt.UTC() ret = db.Save(p) if ret.Error != nil { - return fmt.Errorf("saving %v: %w", p.ID, ret.Error) + return errors.Newf("saving %v: %w", p.ID, ret.Error) } } return nil @@ -366,7 +367,7 @@ var dbMigrations = []dbMigration{ Scan(&estimateBriers) if ret.Error != nil { - return fmt.Errorf("error calculating brier score: %w", ret.Error) + return errors.Newf("error calculating brier score: %w", ret.Error) } for _, r := range estimateBriers { @@ -374,7 +375,7 @@ var dbMigrations = []dbMigration{ Where("id = ?", r.ID). Update("brier_score", r.Brier) if ret.Error != nil { - return fmt.Errorf("error updating brier score: %w", ret.Error) + return errors.Newf("error updating brier score: %w", ret.Error) } } diff --git a/cleosrv/cleosrv/config.go b/cleosrv/cleosrv/config.go index 3dc9bbbb..71ec7d40 100644 --- a/cleosrv/cleosrv/config.go +++ b/cleosrv/cleosrv/config.go @@ -1,11 +1,12 @@ package cleosrv import ( - "fmt" "strings" "github.com/adrg/xdg" "github.com/spf13/viper" + + "github.com/cleodora-forecasting/cleodora/cleoutils/errors" ) const DefaultConfigFileName = "cleosrv" @@ -41,7 +42,7 @@ func (c *Config) LoadWithViper(v *viper.Viper) error { // Note that ConfigFileNotFoundError is not returned when // explicitly specifying a config path (--config), which should // (and does) cause an error if it doesn't exist. - return fmt.Errorf("error reading config file: %w", err) + return errors.Newf("error reading config file: %w", err) } } } diff --git a/cleosrv/graph/resolver.go b/cleosrv/graph/resolver.go index 35cc98c3..a5ceb7ba 100644 --- a/cleosrv/graph/resolver.go +++ b/cleosrv/graph/resolver.go @@ -4,7 +4,6 @@ package graph import ( "context" - "errors" "fmt" "html" "strconv" @@ -15,6 +14,7 @@ import ( "github.com/cleodora-forecasting/cleodora/cleosrv/dbmodel" "github.com/cleodora-forecasting/cleodora/cleosrv/graph/model" + "github.com/cleodora-forecasting/cleodora/cleoutils/errors" ) // This file will not be regenerated automatically. @@ -55,12 +55,12 @@ func createEstimate( estimate model.NewEstimate, ) (*model.Estimate, error) { if err := validateNewEstimate(&estimate, false); err != nil { - return nil, fmt.Errorf("error validating NewEstimate: %w", err) + return nil, errors.Newf("error validating NewEstimate: %w", err) } forecast := dbmodel.Forecast{} ret := tx.Where("id = ?", forecastID).First(&forecast) if ret.Error != nil { - return nil, fmt.Errorf("error getting Forecast with ID %v: %w", forecastID, ret.Error) + return nil, errors.Newf("error getting Forecast with ID %v: %w", forecastID, ret.Error) } if estimate.Created.Before(forecast.Created) { @@ -92,7 +92,7 @@ func createEstimate( ).Where("estimates.forecast_id = ?", forecastID). Distinct().Pluck("outcomes.id", &validOutcomeIds) if ret.Error != nil { - return nil, fmt.Errorf("error getting outcome IDs: %w", ret.Error) + return nil, errors.Newf("error getting outcome IDs: %w", ret.Error) } var submittedOutcomeIds []string @@ -102,12 +102,12 @@ func createEstimate( invalidOutcomeIds := stringSetDiff(submittedOutcomeIds, validOutcomeIds) if len(invalidOutcomeIds) > 0 { - return nil, fmt.Errorf("invalid Outcome IDs: %v", invalidOutcomeIds) + return nil, errors.Newf("invalid Outcome IDs: %v", invalidOutcomeIds) } missingOutcomeIds := stringSetDiff(validOutcomeIds, submittedOutcomeIds) if len(missingOutcomeIds) > 0 { - return nil, fmt.Errorf("missing Outcome IDs: %v", missingOutcomeIds) + return nil, errors.Newf("missing Outcome IDs: %v", missingOutcomeIds) } var probabilities []dbmodel.Probability @@ -115,7 +115,7 @@ func createEstimate( for _, p := range estimate.Probabilities { outcomeID, err := strconv.ParseUint(*p.OutcomeID, 10, 64) if err != nil { - return nil, fmt.Errorf("can't parse %v as uint: %w", outcomeID, err) + return nil, errors.Newf("can't parse %v as uint: %w", outcomeID, err) } probabilities = append( probabilities, @@ -134,7 +134,7 @@ func createEstimate( err := tx.Model(&forecast).Association("Estimates").Append(&dbEstimate) if err != nil { - return nil, fmt.Errorf("error creating Estimate: %w", err) + return nil, errors.Newf("error creating Estimate: %w", err) } return convertEstimateDBToGQL(dbEstimate), nil @@ -192,7 +192,7 @@ func validateNewForecast(forecast *model.NewForecast) error { if forecast.Closes.After(forecast.Resolves) { validationErr = multierror.Append( validationErr, - fmt.Errorf( + errors.Newf( "'Closes' can't be set to a later date than 'Resolves'. "+ "Closes is '%v'. Resolves is '%v'", *forecast.Closes, @@ -217,7 +217,7 @@ func validateNewForecast(forecast *model.NewForecast) error { if forecast.Resolves.Before(*forecast.Created) { validationErr = multierror.Append( validationErr, - fmt.Errorf( + errors.Newf( "'Resolves' can't be set to an earlier date than 'Created'. "+ "Resolves is '%v'. Created is '%v'", forecast.Resolves, @@ -275,7 +275,7 @@ func validateNewEstimate(estimate *model.NewEstimate, duringCreateForecast bool) if _, ok := existingOutcomes[p.Outcome.Text]; ok { validationErr = multierror.Append( validationErr, - fmt.Errorf("outcome '%v' is a duplicate", p.Outcome.Text), + errors.Newf("outcome '%v' is a duplicate", p.Outcome.Text), ) } existingOutcomes[p.Outcome.Text] = true @@ -302,7 +302,7 @@ func validateNewEstimate(estimate *model.NewEstimate, duringCreateForecast bool) if p.Value < 0 || p.Value > 100 { validationErr = multierror.Append( validationErr, - fmt.Errorf("probabilities must be between 0 and 100, not %v", p.Value), + errors.Newf("probabilities must be between 0 and 100, not %v", p.Value), ) } sumProbabilities += p.Value @@ -310,7 +310,7 @@ func validateNewEstimate(estimate *model.NewEstimate, duringCreateForecast bool) if sumProbabilities != 100 { validationErr = multierror.Append( validationErr, - fmt.Errorf("probabilities must add up to 100, not %v", sumProbabilities), + errors.Newf("probabilities must add up to 100, not %v", sumProbabilities), ) } @@ -320,7 +320,7 @@ func validateNewEstimate(estimate *model.NewEstimate, duringCreateForecast bool) if estimate.Created.After(now) { validationErr = multierror.Append( validationErr, - fmt.Errorf( + errors.Newf( "'created' can't be in the future: %v", estimate.Created, ), diff --git a/cleosrv/graph/schema.resolvers.go b/cleosrv/graph/schema.resolvers.go index 791226c8..6bf3cdb6 100644 --- a/cleosrv/graph/schema.resolvers.go +++ b/cleosrv/graph/schema.resolvers.go @@ -6,7 +6,6 @@ package graph import ( "context" - "errors" "fmt" "html" "time" @@ -15,6 +14,7 @@ import ( "github.com/cleodora-forecasting/cleodora/cleosrv/graph/generated" "github.com/cleodora-forecasting/cleodora/cleosrv/graph/model" "github.com/cleodora-forecasting/cleodora/cleoutils" + errors2 "github.com/cleodora-forecasting/cleodora/cleoutils/errors" "gorm.io/gorm" ) @@ -22,14 +22,14 @@ import ( func (r *mutationResolver) CreateForecast(ctx context.Context, forecast model.NewForecast, estimate model.NewEstimate) (*model.Forecast, error) { err := validateNewForecast(&forecast) if err != nil { - return nil, fmt.Errorf("error validating NewForecast: %w", err) + return nil, errors2.Newf("error validating NewForecast: %w", err) } // We want the first estimate to have the same 'Created' time as the // forecast itself because it's logical that it would be that way. estimate.Created = forecast.Created err = validateNewEstimate(&estimate, true) if err != nil { - return nil, fmt.Errorf("error validating NewEstimate: %w", err) + return nil, errors2.Newf("error validating NewEstimate: %w", err) } dbForecast := dbmodel.Forecast{ Title: html.EscapeString(forecast.Title), @@ -46,7 +46,7 @@ func (r *mutationResolver) CreateForecast(ctx context.Context, forecast model.Ne return ret.Error }) if err != nil { - return nil, fmt.Errorf("creating forecast: %w", err) + return nil, errors2.Newf("creating forecast: %w", err) } retForecast := model.Forecast{ @@ -71,7 +71,7 @@ func (r *mutationResolver) ResolveForecast(ctx context.Context, forecastID strin } }() if err := tx.Error; err != nil { - return nil, fmt.Errorf("error creating transaction: %w", err) + return nil, errors2.Newf("error creating transaction: %w", err) } resolutionToSet := dbmodel.ResolutionResolved @@ -81,12 +81,12 @@ func (r *mutationResolver) ResolveForecast(ctx context.Context, forecastID strin if resolutionToSet == dbmodel.ResolutionUnresolved { _ = tx.Rollback() - return nil, fmt.Errorf("resolution %v is not allowed", resolutionToSet) + return nil, errors2.Newf("resolution %v is not allowed", resolutionToSet) } if resolutionToSet == dbmodel.ResolutionResolved && correctOutcomeID == nil { _ = tx.Rollback() - return nil, fmt.Errorf( + return nil, errors2.Newf( "to resolve as %v, an Outcome must be specified", resolutionToSet, ) @@ -96,12 +96,12 @@ func (r *mutationResolver) ResolveForecast(ctx context.Context, forecastID strin ret := tx.Where("id = ?", forecastID).First(&forecast) if ret.Error != nil { _ = tx.Rollback() - return nil, fmt.Errorf("error getting Forecast with ID %v: %w", forecastID, ret.Error) + return nil, errors2.Newf("error getting Forecast with ID %v: %w", forecastID, ret.Error) } if forecast.Resolution != dbmodel.ResolutionUnresolved { _ = tx.Rollback() - return nil, errors.New("forecast has already been resolved") + return nil, errors2.New("forecast has already been resolved") } forecast.Resolution = resolutionToSet @@ -115,7 +115,7 @@ func (r *mutationResolver) ResolveForecast(ctx context.Context, forecastID strin ret = tx.Save(&forecast) if ret.Error != nil { _ = tx.Rollback() - return nil, fmt.Errorf("error setting resolution: %w", ret.Error) + return nil, errors2.Newf("error setting resolution: %w", ret.Error) } if resolutionToSet == dbmodel.ResolutionResolved { @@ -123,7 +123,7 @@ func (r *mutationResolver) ResolveForecast(ctx context.Context, forecastID strin ret = tx.Where("id = ?", correctOutcomeID).First(&outcome) if ret.Error != nil { _ = tx.Rollback() - return nil, fmt.Errorf("error getting outcome: %w", ret.Error) + return nil, errors2.Newf("error getting outcome: %w", ret.Error) } matchingForecast := dbmodel.Forecast{} @@ -139,19 +139,19 @@ func (r *mutationResolver) ResolveForecast(ctx context.Context, forecastID strin if ret.Error != nil { _ = tx.Rollback() - return nil, fmt.Errorf("can't match forecast and outcome: %w", ret.Error) + return nil, errors2.Newf("can't match forecast and outcome: %w", ret.Error) } if ret.RowsAffected != 1 { _ = tx.Rollback() - return nil, errors.New("can't match forecast and outcome") + return nil, errors2.New("can't match forecast and outcome") } outcome.Correct = true ret = tx.Save(&outcome) if ret.Error != nil { _ = tx.Rollback() - return nil, fmt.Errorf("error updating outcome: %w", ret.Error) + return nil, errors2.Newf("error updating outcome: %w", ret.Error) } type EstimateBrier struct { @@ -182,7 +182,7 @@ func (r *mutationResolver) ResolveForecast(ctx context.Context, forecastID strin if ret.Error != nil { _ = tx.Rollback() - return nil, fmt.Errorf("error calculating brier score: %w", ret.Error) + return nil, errors2.Newf("error calculating brier score: %w", ret.Error) } for _, r := range estimateBriers { @@ -191,7 +191,7 @@ func (r *mutationResolver) ResolveForecast(ctx context.Context, forecastID strin Update("brier_score", r.Brier) if ret.Error != nil { _ = tx.Rollback() - return nil, fmt.Errorf("error updating brier score: %w", ret.Error) + return nil, errors2.Newf("error updating brier score: %w", ret.Error) } } } @@ -200,7 +200,7 @@ func (r *mutationResolver) ResolveForecast(ctx context.Context, forecastID strin ret = tx.Preload("Estimates.Probabilities.Outcome").Find(&forecast) if ret.Error != nil { _ = tx.Rollback() - return nil, fmt.Errorf("error preloading: %w", ret.Error) + return nil, errors2.Newf("error preloading: %w", ret.Error) } var estimates []*model.Estimate @@ -243,7 +243,7 @@ func (r *mutationResolver) ResolveForecast(ctx context.Context, forecastID strin } ret = tx.Commit() if ret.Error != nil { - return nil, fmt.Errorf("error committing: %w", ret.Error) + return nil, errors2.Newf("error committing: %w", ret.Error) } return &rf, nil } diff --git a/cleosrv/integrationtest/create_test_sql/main.go b/cleosrv/integrationtest/create_test_sql/main.go index 0b5c69b8..3945cb24 100644 --- a/cleosrv/integrationtest/create_test_sql/main.go +++ b/cleosrv/integrationtest/create_test_sql/main.go @@ -11,7 +11,6 @@ package main import ( "bytes" "context" - "errors" "fmt" "os" "os/exec" @@ -22,6 +21,7 @@ import ( "github.com/Khan/genqlient/graphql" "github.com/cleodora-forecasting/cleodora/cleosrv/integrationtest" + "github.com/cleodora-forecasting/cleodora/cleoutils/errors" ) func main() { @@ -86,7 +86,7 @@ Example: version, err := getVersion(c) if err != nil { - return fmt.Errorf("getting version: %w", err) + return errors.Newf("getting version: %w", err) } fmt.Println("cleosrv version:", version) @@ -96,7 +96,7 @@ Example: err = cleosrvCmd.Process.Kill() if err != nil { - return fmt.Errorf("stopping cleosrvCmd: %w", err) + return errors.Newf("stopping cleosrvCmd: %w", err) } err = integrationtest.CopyFile(dbPath, resultDb) @@ -137,10 +137,10 @@ func executeQueries(c graphql.Client, version string) error { } resp, err := integrationtest.CreateForecast(context.Background(), c, f1, e1) if err != nil { - return fmt.Errorf("create f1: %w", err) + return errors.Newf("create f1: %w", err) } if resp.CreateForecast.Id == "" { - return fmt.Errorf("unexpected response f1: %v", resp) + return errors.Newf("unexpected response f1: %v", resp) } // Create another forecast with 'created', 'resolves' and 'closes' in the @@ -149,7 +149,7 @@ func executeQueries(c graphql.Client, version string) error { newYork, err := time.LoadLocation("America/New_York") if err != nil { - return fmt.Errorf("can't get TZ loc: %w", err) + return errors.Newf("can't get TZ loc: %w", err) } f2 := integrationtest.NewForecast{ @@ -177,10 +177,10 @@ func executeQueries(c graphql.Client, version string) error { } resp, err = integrationtest.CreateForecast(context.Background(), c, f2, e2) if err != nil { - return fmt.Errorf("create f2: %w", err) + return errors.Newf("create f2: %w", err) } if resp.CreateForecast.Id == "" { - return fmt.Errorf("unexpected response f2: %v", resp) + return errors.Newf("unexpected response f2: %v", resp) } f3 := integrationtest.NewForecast{ @@ -211,10 +211,10 @@ func executeQueries(c graphql.Client, version string) error { } resp, err = integrationtest.CreateForecast(context.Background(), c, f3, e3) if err != nil { - return fmt.Errorf("create f3: %w", err) + return errors.Newf("create f3: %w", err) } if resp.CreateForecast.Id == "" { - return fmt.Errorf("unexpected response f3: %v", resp) + return errors.Newf("unexpected response f3: %v", resp) } // Resolve the forecast f3 @@ -226,7 +226,7 @@ func executeQueries(c graphql.Client, version string) error { } } if yesOutcomeId == "" { - return fmt.Errorf("could not find outcome 'Yes': %v", resp) + return errors.Newf("could not find outcome 'Yes': %v", resp) } // Backport this script to 0.2.0 then overwrite the DB @@ -239,14 +239,14 @@ func executeQueries(c graphql.Client, version string) error { &resolutionResolved, ) if err != nil { - return fmt.Errorf("resolve f3 err: %w", err) + return errors.Newf("resolve f3 err: %w", err) } if resolveResp.ResolveForecast.Resolution != integrationtest.ResolutionResolved { - return fmt.Errorf("resolution is not RESOLVED: %v", resolveResp) + return errors.Newf("resolution is not RESOLVED: %v", resolveResp) } if resolveResp.ResolveForecast.Id != f3Id { - return fmt.Errorf("the IDs don't match: %v", resolveResp) + return errors.Newf("the IDs don't match: %v", resolveResp) } return nil diff --git a/cleosrv/integrationtest/helper.go b/cleosrv/integrationtest/helper.go index af5a24ca..75a0fe96 100644 --- a/cleosrv/integrationtest/helper.go +++ b/cleosrv/integrationtest/helper.go @@ -17,6 +17,7 @@ import ( "github.com/cleodora-forecasting/cleodora/cleosrv/cleosrv" "github.com/cleodora-forecasting/cleodora/cleosrv/graph" "github.com/cleodora-forecasting/cleodora/cleosrv/graph/generated" + "github.com/cleodora-forecasting/cleodora/cleoutils/errors" ) // initServerAndGetClient returns a graphql.Client generated by genqlient @@ -83,20 +84,20 @@ func CopyFile(src string, dst string) error { // Open original file srcF, err := os.Open(src) if err != nil { - return fmt.Errorf("open src: %w", err) + return errors.Newf("open src: %w", err) } defer func() { _ = srcF.Close() }() // Create new file dstF, err := os.Create(dst) if err != nil { - return fmt.Errorf("open dst: %w", err) + return errors.Newf("open dst: %w", err) } defer func() { _ = dstF.Close() }() _, err = io.Copy(dstF, srcF) if err != nil { - return fmt.Errorf("copying file: %w", err) + return errors.Newf("copying file: %w", err) } return nil } diff --git a/cleoutils/errors/errors.go b/cleoutils/errors/errors.go new file mode 100644 index 00000000..67ac03ac --- /dev/null +++ b/cleoutils/errors/errors.go @@ -0,0 +1,33 @@ +// Package errors is a wrapper for github.com/cockroachdb/errors +// to make it easier to replace later, if necessary. +package errors + +import "github.com/cockroachdb/errors" + +func New(msg string) error { + return errors.New(msg) +} + +func Newf(format string, args ...interface{}) error { + return errors.Newf(format, args...) +} + +func Wrap(err error, msg string) error { + return errors.Wrap(err, msg) +} + +func Wrapf(err error, msg string, args ...interface{}) error { + return errors.Wrapf(err, msg, args...) +} + +func WithHint(err error, msg string) error { + return errors.WithHint(err, msg) +} + +func WithHintf(err error, format string, args ...interface{}) error { + return errors.WithHintf(err, format, args...) +} + +func FlattenHints(err error) string { + return errors.FlattenHints(err) +} diff --git a/go.mod b/go.mod index cd551ee7..ebe95acf 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/Khan/genqlient v0.6.0 github.com/adrg/xdg v0.4.0 github.com/carolynvs/magex v0.9.0 + github.com/cockroachdb/errors v1.2.4 github.com/glebarez/sqlite v1.9.0 github.com/go-chi/chi/v5 v5.0.10 github.com/golangci/golangci-lint v1.53.3 @@ -118,12 +119,14 @@ require ( github.com/caarlos0/log v0.4.2 // indirect github.com/cavaliergopher/cpio v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect + github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/charithe/durationcheck v0.0.10 // indirect github.com/charmbracelet/lipgloss v0.7.1 // indirect github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect github.com/chrismellard/docker-credential-acr-env v0.0.0-20220327082430-c57b701bfc08 // indirect github.com/cloudflare/circl v1.3.3 // indirect + github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect @@ -155,6 +158,7 @@ require ( github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect + github.com/getsentry/raven-go v0.2.0 // indirect github.com/glebarez/go-sqlite v1.21.2 // indirect github.com/go-critic/go-critic v0.8.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect diff --git a/go.sum b/go.sum index 9b72250b..8f3eccc7 100644 --- a/go.sum +++ b/go.sum @@ -1017,6 +1017,7 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -1071,7 +1072,9 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWH github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= +github.com/cockroachdb/errors v1.2.4 h1:Lap807SXTH5tri2TivECb/4abUkMZC9zRoLarvcKDqs= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= @@ -1366,6 +1369,7 @@ github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= +github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=