mirror of
https://github.com/hanzo-fi/payments.git
synced 2026-10-30 20:31:20 +00:00
71 lines
1.6 KiB
Go
71 lines
1.6 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/formancehq/go-libs/v3/logging"
|
|
"github.com/jackc/pgx/v5/pgconn"
|
|
"github.com/pkg/errors"
|
|
"github.com/uptrace/bun"
|
|
)
|
|
|
|
var (
|
|
ErrValidation = errors.New("validation error")
|
|
ErrNotFound = errors.New("not found")
|
|
ErrDuplicateKeyValue = errors.New("object already exists")
|
|
// Don't want to expose the internal that is a foreign key violation to the
|
|
// client through the API
|
|
ErrForeignKeyViolation = errors.New("value not found")
|
|
)
|
|
|
|
var FKViolationColumn = []string{
|
|
"connector_id",
|
|
"bank_account_id",
|
|
"payment_id",
|
|
"pool_id",
|
|
"schedule_id",
|
|
"payment_initiation_id",
|
|
"payment_initiation_reversal_id",
|
|
}
|
|
|
|
func e(msg string, err error) error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
|
|
var pgErr *pgconn.PgError
|
|
if errors.As(err, &pgErr) && pgErr.Code == "23505" {
|
|
return ErrDuplicateKeyValue
|
|
}
|
|
|
|
if errors.As(err, &pgErr) && pgErr.Code == "23503" {
|
|
for _, column := range FKViolationColumn {
|
|
if strings.Contains(pgErr.ConstraintName, column) {
|
|
return fmt.Errorf("%s: %w", column, ErrForeignKeyViolation)
|
|
}
|
|
}
|
|
|
|
return ErrForeignKeyViolation
|
|
}
|
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return ErrNotFound
|
|
}
|
|
|
|
return fmt.Errorf("%s: %w", msg, err)
|
|
}
|
|
|
|
// meant to be called in defer block
|
|
func rollbackOnTxError(ctx context.Context, tx *bun.Tx, err error) {
|
|
if err == nil {
|
|
return
|
|
}
|
|
|
|
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
|
logging.FromContext(ctx).WithField("original_error", err.Error()).Errorf("failed to rollback transaction: %w", rollbackErr)
|
|
}
|
|
}
|