package sqlite import ( "database/sql" "errors" "code.nochebuena.dev/go/xerrors" ) // coder is the duck-type interface for SQLite extended error codes. // modernc.org/sqlite errors implement this interface. type coder interface{ Code() int } const ( sqliteConstraintPrimaryKey = 1555 sqliteConstraintUnique = 2067 sqliteConstraintForeignKey = 787 ) // HandleError maps SQLite and database/sql errors to xerrors types. func HandleError(err error) error { if err == nil { return nil } if errors.Is(err, sql.ErrNoRows) { return xerrors.New(xerrors.ErrNotFound, "record not found").WithError(err) } var ce coder if errors.As(err, &ce) { switch ce.Code() { case sqliteConstraintUnique, sqliteConstraintPrimaryKey: return xerrors.New(xerrors.ErrAlreadyExists, "record already exists").WithError(err) case sqliteConstraintForeignKey: return xerrors.New(xerrors.ErrInvalidInput, "data integrity violation").WithError(err) } } return xerrors.New(xerrors.ErrInternal, "unexpected database error").WithError(err) }