Skip to main content
Version: 0.7.0

Errors API Reference

Sentinel Errors

var (
ErrNotFound = errors.New("record not found")
ErrInvalidModel = errors.New("invalid model")
ErrInvalidQuery = errors.New("invalid query")
ErrInvalidIdentifier = errors.New("invalid identifier")
ErrInvalidJSONPath = errors.New("invalid JSON path")
ErrInvalidJoin = errors.New("invalid JOIN ON clause")
ErrStaleEntity = errors.New("stale entity (optimistic-locking conflict)")
ErrUnsupportedFeature = errors.New("feature not supported by dialect")
ErrInvalidTimezone = errors.New("invalid column timezone")
ErrDialectNotSupported = errors.New("dialect not supported")
ErrConnection = errors.New("database connection error")
ErrTimeout = errors.New("query timeout")
ErrConstraintViolation = errors.New("constraint violation")
)

ErrInvalidJSONPath is returned when WhereJSON receives a path that does not match the dotted identifier grammar ^[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*$ (max 256 chars). Quark binds the path as a parameter in every dialect, but rejects malformed paths at the API surface so callers fail fast with a clear error rather than producing surprising SQL.

ErrUnsupportedFeature is returned by builder methods (e.g. ForUpdate on SQLite, NoWait on SQL Server) when the active dialect does not implement the requested feature. The error message includes the dialect name and the specific gap so callers can branch by dialect or fall back to a different strategy. Useful with errors.Is to check whether a soft fallback is appropriate (e.g. drop down to a transaction-level lock).

ErrStaleEntity is returned when an Update / UpdateFields / Tracked.Save on a model carrying a quark:"version" field would have written an already-advanced row — the version predicate didn't match, no rows were written, and the caller must reload + replay or surface the conflict. See Optimistic Locking for the column-tag contract and an example retry pattern.

ErrInvalidJoin is returned when Join/LeftJoin/RightJoin receives an ON clause that does not match the minimal identifier-only grammar enforced by internal/guard.ValidateJoinOn. The grammar accepts identifier-to-identifier comparisons (a.b = c.d) joined by AND/OR and the operators =, !=, <>, <, <=, >, >=. Literals, function calls, subqueries, and parentheses are rejected — the string-raw form is deprecated and will be replaced by a structured builder in v0.4.

ErrInvalidTimezone is returned by Client.RegisterModel and Client.Migrate when a model field carries a quark:"tz=..." tag whose value is not a valid IANA timezone name (time.LoadLocation rejected it). It is surfaced fail-fast — the model is rejected at registration or migration time, not on the first query that binds or scans the column. The wrapped error names the field, the column and the offending timezone string. See Timezones for the per-column timezone contract.

Error Checking

user, err := quark.For[User](ctx, client).Find(id)
if errors.Is(err, quark.ErrNotFound) {
return nil, fmt.Errorf("user %d not found", id)
}
if errors.Is(err, quark.ErrTimeout) {
// Retry with backoff
}
if errors.Is(err, quark.ErrConstraintViolation) {
// Handle duplicate key, FK violation, etc.
}

Error Wrapping

Quark wraps database errors with context:

// Timeout errors wrap context.DeadlineExceeded
if errors.Is(err, context.DeadlineExceeded) {
// Detected as ErrTimeout
}

// Constraint violations detected across dialects
// PostgreSQL: "unique constraint", "foreign key constraint"
// MySQL: "duplicate entry", "foreign key constraint fails"
// SQLite: "unique constraint failed"