Add db/errors.go, move error definitions to it

This commit is contained in:
wispem-wantex 2025-11-08 19:23:38 -08:00
parent 8c6d8354df
commit 6a837d28c6
2 changed files with 76 additions and 5 deletions

View File

@ -22,10 +22,6 @@ var (
version_number uint
)
var (
ErrTargetExists = errors.New("target already exists")
)
// Colors for terminal output
const (
ColorReset = "\033[0m"
@ -51,7 +47,7 @@ func Create(path string) (*sqlx.DB, error) {
// First check if the path already exists
_, err := os.Stat(path)
if err == nil {
return nil, ErrTargetExists
return nil, ErrDatabaseAlreadyExists
} else if !errors.Is(err, os.ErrNotExist) {
return nil, fmt.Errorf("path error: %w", err)
}

75
pkg/db/errors.go Normal file
View File

@ -0,0 +1,75 @@
package db
import (
"errors"
"fmt"
"github.com/mattn/go-sqlite3"
)
var (
ErrNotInDB = errors.New("not in db")
ErrItemIsDeleted = errors.New("item is deleted")
ErrForeignKeyViolation = errors.New("foreign key constraint failed")
ErrDatabaseAlreadyExists = errors.New("target already exists")
)
type ForeignKey interface {
~uint64 | ~string
}
type ForeignKeyError[T ForeignKey] struct {
Field string
TargetTable string
FkValue T
}
func NewForeignKeyError[T ForeignKey](field, table string, fkValue T) ForeignKeyError[T] {
return ForeignKeyError[T]{
Field: field,
TargetTable: table,
FkValue: fkValue,
}
}
func (e ForeignKeyError[T]) Error() string {
return fmt.Sprintf(`%s: fk field %q (to %q) with value "%v"`,
ErrForeignKeyViolation.Error(), e.Field, e.TargetTable, e.FkValue,
)
}
// Unwrap returns the sentinel error-- permits the use of errors.Is for convenience
func (e ForeignKeyError[T]) Unwrap() error {
return ErrForeignKeyViolation
}
// -------------
// SQLite errors
// -------------
// IsSqliteFkError checks whether an error is a SQLite foreign key constraint violation.
func IsSqliteFkError(err error) bool {
var sqliteErr sqlite3.Error
if !errors.As(err, &sqliteErr) {
return false
}
return errors.Is(sqliteErr.ExtendedCode, sqlite3.ErrConstraintForeignKey)
}
// IsSqliteUniqError checks whether an error is a SQLite unique constraint violation.
func IsSqliteUniqError(err error) bool {
var sqliteErr sqlite3.Error
if !errors.As(err, &sqliteErr) {
return false
}
return errors.Is(sqliteErr.ExtendedCode, sqlite3.ErrConstraintUnique)
}
// IsSqliteNotNullError checks whether an error is a SQLite not null constraint violation.
func IsSqliteNotNullError(err error) bool {
var sqliteErr sqlite3.Error
if !errors.As(err, &sqliteErr) {
return false
}
return errors.Is(sqliteErr.ExtendedCode, sqlite3.ErrConstraintNotNull)
}