sq/drivers/postgres/errors.go

62 lines
1.5 KiB
Go
Raw Normal View History

package postgres
import (
"errors"
"github.com/neilotoole/sq/libsq/core/errz"
"github.com/jackc/pgx/v5/pgconn"
)
// errw wraps any error from the db. It should be called at
// every interaction with the db. If err is nil, nil is returned.
// Certain errors will be wrapped in specific error types,
// e.g, errz.NotExistError.
func errw(err error) error {
switch {
case err == nil:
return nil
case hasErrCode(err, errCodeRelationNotExist):
return errz.NotExist(err)
default:
return errz.Err(err)
}
}
const (
errCodeRelationNotExist = "42P01"
errCodeTooManyConnections = "53300"
)
// isErrTooManyConnections returns true if err is a postgres error
// with code 53300 (too_many_connections).
//
// See: https://www.postgresql.org/docs/14/errcodes-appendix.html
func isErrTooManyConnections(err error) bool {
return hasErrCode(err, errCodeTooManyConnections)
}
// isErrRelationNotExist returns true if err is a postgres error
// with code 42P01 (undefined_table).
//
// See: https://www.postgresql.org/docs/14/errcodes-appendix.html
func isErrRelationNotExist(err error) bool {
return hasErrCode(err, errCodeRelationNotExist)
}
// hasErrCode returns true if err (or its cause error)
// is of type *pgconn.PgError and err.Number equals code.
// See: isErrTooManyConnections.
func hasErrCode(err error, code string) bool {
if err == nil {
return false
}
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) {
return pgErr.Code == code
}
return false
}