diff --git a/apperr/apperr.go b/apperr/apperr.go new file mode 100644 index 0000000..69d86ea --- /dev/null +++ b/apperr/apperr.go @@ -0,0 +1,57 @@ +package apperr + +import ( + "fmt" + "runtime" +) + +// Component defines where the error occurred +type Component string + +const ( + DataLayer Component = "DataLayer" + LogicLayer Component = "LogicLayer" + APILayer Component = "APILayer" +) + +// AppError is our custom error type +type AppError struct { + Component Component // Where it failed + PublicMessage string // Safe to show to the end-user + OriginalErr error // The actual error that triggered this + File string // Traceback: File name + Line int // Traceback: Line number +} + +// New creates a new AppError and captures the caller's traceback automatically +func New(comp Component, publicMsg string, err error) *AppError { + _, file, line, ok := runtime.Caller(1) + if !ok { + file = "unknown" + line = 0 + } + + return &AppError{ + Component: comp, + PublicMessage: publicMsg, + OriginalErr: err, + File: file, + Line: line, + } +} + +func (e *AppError) Error() string { + if e.OriginalErr != nil { + return fmt.Sprintf("[%s] %s:%d - %s: %v", e.Component, e.File, e.Line, e.PublicMessage, e.OriginalErr) + } + return fmt.Sprintf("[%s] %s:%d - %s", e.Component, e.File, e.Line, e.PublicMessage) +} + +func (e *AppError) Unwrap() error { + return e.OriginalErr +} + +// ClientError provides the safe message for the API/CLI response. +func (e *AppError) ClientError() string { + return e.PublicMessage +} \ No newline at end of file diff --git a/testing/dockertestx/minio_migrate.go b/testing/dockertestx/minio_migrate.go index 7cb35b2..8625e19 100644 --- a/testing/dockertestx/minio_migrate.go +++ b/testing/dockertestx/minio_migrate.go @@ -8,6 +8,7 @@ import ( "github.com/ory/dockertest/v3" "github.com/ory/dockertest/v3/docker" + "github.com/raystack/salt/apperr" ) const waitContainerTimeout = 60 * time.Second @@ -56,7 +57,11 @@ func MigrateMinio(minioHost string, bucketName string, opts ...dockerMigrateMini if dm.pool == nil { dm.pool, err = dockertest.NewPool("") if err != nil { - return fmt.Errorf("could not create dockertest pool: %w", err) + return apperr.New( + apperr.DataLayer, + "Could not create dockertest pool", //for user + err, //for logger + ) } }