You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
loop/loopdb/sqlerrors.go

72 lines
1.8 KiB
Go

package loopdb
import (
"errors"
"fmt"
"github.com/jackc/pgconn"
"github.com/jackc/pgerrcode"
"modernc.org/sqlite"
sqlite3 "modernc.org/sqlite/lib"
)
// MapSQLError attempts to interpret a given error as a database agnostic SQL
// error.
func MapSQLError(err error) error {
// Attempt to interpret the error as a sqlite error.
var sqliteErr *sqlite.Error
if errors.As(err, &sqliteErr) {
return parseSqliteError(sqliteErr)
}
// Attempt to interpret the error as a postgres error.
var pqErr *pgconn.PgError
if errors.As(err, &pqErr) {
return parsePostgresError(pqErr)
}
// Return original error if it could not be classified as a database
// specific error.
return err
}
// parsePostgresError attempts to parse a sqlite error as a database agnostic
// SQL error.
func parseSqliteError(sqliteErr *sqlite.Error) error {
switch sqliteErr.Code() {
// Handle unique constraint violation error.
case sqlite3.SQLITE_CONSTRAINT_UNIQUE:
return &ErrSqlUniqueConstraintViolation{
DbError: sqliteErr,
}
default:
return fmt.Errorf("unknown sqlite error: %w", sqliteErr)
}
}
// parsePostgresError attempts to parse a postgres error as a database agnostic
// SQL error.
func parsePostgresError(pqErr *pgconn.PgError) error {
switch pqErr.Code {
// Handle unique constraint violation error.
case pgerrcode.UniqueViolation:
return &ErrSqlUniqueConstraintViolation{
DbError: pqErr,
}
default:
return fmt.Errorf("unknown postgres error: %w", pqErr)
}
}
// ErrSqlUniqueConstraintViolation is an error type which represents a database
// agnostic SQL unique constraint violation.
type ErrSqlUniqueConstraintViolation struct {
DbError error
}
func (e ErrSqlUniqueConstraintViolation) Error() string {
return fmt.Sprintf("sql unique constraint violation: %v", e.DbError)
}