Files
Sylvain RabotandGitHub ceabd4cd1a refactor: replace github.com/pkg/errors with stdlib errors (#661)
Migrate all internal usages of github.com/pkg/errors to the Go standard
library: errors.New/Is/As map directly to the stdlib equivalents, while
errors.Wrap/Wrapf become fmt.Errorf(..., %w, err). github.com/pkg/errors
is no longer a direct dependency (remains indirect via watermill).

Constraint: errors.Wrap returns nil on nil input; fmt.Errorf does not, so
run.go's "executing migration" wrap was rewritten as an explicit nil check
Confidence: high
Scope-risk: narrow
2026-07-07 09:11:30 +00:00

216 lines
4.5 KiB
Go

package postgres
import (
"database/sql"
"errors"
"github.com/jackc/pgerrcode"
"github.com/jackc/pgx/v5/pgconn"
)
// ResolveError is an helper to wrap postgres errors into storage errors
func ResolveError(err error) error {
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return ErrNotFound
}
var pge *pgconn.PgError
switch {
case errors.As(err, &pge):
switch pge.Code {
case pgerrcode.NotNullViolation, pgerrcode.InvalidTextRepresentation:
return newErrValidationFailed(pge)
case pgerrcode.ForeignKeyViolation:
return newErrFkConstraintFailed(pge)
case pgerrcode.UniqueViolation:
return newErrConstraintsFailed(pge)
case pgerrcode.TooManyConnections:
return newErrTooManyClient(err)
case pgerrcode.DeadlockDetected:
return ErrDeadlockDetected
case pgerrcode.ReadOnlySQLTransaction:
return ErrReadOnlyTransaction
case pgerrcode.SerializationFailure:
return ErrSerialization
case pgerrcode.UndefinedTable:
return ErrMissingTable
case pgerrcode.InvalidSchemaName:
return ErrMissingSchema
case pgerrcode.CheckViolation:
return newErrCheckViolation(pge)
case pgerrcode.RaiseException:
return newErrRaisedException(pge)
}
}
return err
}
return nil
}
var (
ErrNotFound = errors.New("not found")
ErrDeadlockDetected = errors.New("deadlock detected")
ErrReadOnlyTransaction = errors.New("read-only transaction")
ErrSerialization = errors.New("serialization error")
ErrMissingTable = errors.New("missing table")
ErrMissingSchema = errors.New("missing schema")
)
func IsNotFoundError(err error) bool {
return errors.Is(err, ErrNotFound)
}
type ErrFKConstraintFailed struct {
err *pgconn.PgError
}
func (e ErrFKConstraintFailed) Error() string {
return e.err.Error()
}
func (e ErrFKConstraintFailed) Is(err error) bool {
var errFKConstraintFailed ErrFKConstraintFailed
ok := errors.As(err, &errFKConstraintFailed)
return ok
}
func (e ErrFKConstraintFailed) Unwrap() error {
return e.err
}
func (e ErrFKConstraintFailed) GetConstraint() string {
return e.err.ConstraintName
}
func newErrFkConstraintFailed(err *pgconn.PgError) ErrFKConstraintFailed {
return ErrFKConstraintFailed{
err: err,
}
}
type ErrValidationFailed struct {
err *pgconn.PgError
}
func (e ErrValidationFailed) Error() string {
return e.err.Error()
}
func (e ErrValidationFailed) Is(err error) bool {
var errValidationFailed ErrValidationFailed
ok := errors.As(err, &errValidationFailed)
return ok
}
func (e ErrValidationFailed) Unwrap() error {
return e.err
}
func (e ErrValidationFailed) Message() string {
return e.err.Message
}
func newErrValidationFailed(err *pgconn.PgError) ErrValidationFailed {
return ErrValidationFailed{
err: err,
}
}
// ErrConstraintsFailed wraps 23505 pg error, meaning uniqueness constraint failed
type ErrConstraintsFailed struct {
err *pgconn.PgError
}
func (e ErrConstraintsFailed) Error() string {
return e.err.Error()
}
func (e ErrConstraintsFailed) Is(err error) bool {
var errConstraintsFailed ErrConstraintsFailed
ok := errors.As(err, &errConstraintsFailed)
return ok
}
func (e ErrConstraintsFailed) Unwrap() error {
return e.err
}
func (e ErrConstraintsFailed) GetConstraint() string {
return e.err.ConstraintName
}
func newErrConstraintsFailed(err *pgconn.PgError) ErrConstraintsFailed {
return ErrConstraintsFailed{
err: err,
}
}
type ErrCheckViolation struct {
err *pgconn.PgError
}
func (e ErrCheckViolation) Error() string {
return e.err.Error()
}
func (e ErrCheckViolation) Is(err error) bool {
var errChecks ErrCheckViolation
ok := errors.As(err, &errChecks)
return ok
}
func (e ErrCheckViolation) Unwrap() error {
return e.err
}
func newErrCheckViolation(err *pgconn.PgError) ErrCheckViolation {
return ErrCheckViolation{
err: err,
}
}
type ErrTooManyClient struct {
err error
}
func (e ErrTooManyClient) Error() string {
return e.err.Error()
}
func newErrTooManyClient(err error) ErrTooManyClient {
return ErrTooManyClient{
err: err,
}
}
type ErrRaisedException struct {
err *pgconn.PgError
}
func (e ErrRaisedException) Error() string {
return e.err.Error()
}
func (e ErrRaisedException) Is(err error) bool {
var errRaisedException ErrRaisedException
ok := errors.As(err, &errRaisedException)
return ok
}
func (e ErrRaisedException) Unwrap() error {
return e.err
}
func (e ErrRaisedException) GetMessage() string {
return e.err.Message
}
func newErrRaisedException(err *pgconn.PgError) ErrRaisedException {
return ErrRaisedException{
err: err,
}
}