errors.go

 1package db
 2
 3import (
 4	"database/sql"
 5	"errors"
 6
 7	"github.com/lib/pq"
 8	sqlite "modernc.org/sqlite"
 9	sqlitelib "modernc.org/sqlite/lib"
10)
11
12var (
13	// ErrDuplicateKey is a constraint violation error.
14	ErrDuplicateKey = errors.New("duplicate key value violates table constraint")
15
16	// ErrRecordNotFound is returned when a record is not found.
17	ErrRecordNotFound = sql.ErrNoRows
18)
19
20// WrapError is a convenient function that unite various database driver
21// errors to consistent errors.
22func WrapError(err error) error {
23	if err != nil { //nolint:nestif
24		if errors.Is(err, sql.ErrNoRows) {
25			return ErrRecordNotFound
26		}
27
28		// Handle sqlite constraint error.
29		if liteErr, ok := err.(*sqlite.Error); ok {
30			code := liteErr.Code()
31			if code == sqlitelib.SQLITE_CONSTRAINT_PRIMARYKEY ||
32				code == sqlitelib.SQLITE_CONSTRAINT_FOREIGNKEY ||
33				code == sqlitelib.SQLITE_CONSTRAINT_UNIQUE {
34				return ErrDuplicateKey
35			}
36		}
37
38		// Handle postgres constraint error.
39		if pgErr, ok := err.(*pq.Error); ok {
40			if pgErr.Code == "23505" ||
41				pgErr.Code == "23503" ||
42				pgErr.Code == "23514" {
43				return ErrDuplicateKey
44			}
45		}
46	}
47	return err
48}