# gizdb:error

Typed failures shared by database owners; protocol spelling lives in sql/errors.giz.

```gizlang
import * as Error from "gizdb:error";
```

## Types

### `QueryErrorKind`

```gizlang
type QueryErrorKind = | { kind: "invalid_role_grant"; } | { kind: "invalid_window"; } | { kind: "bad_copy"; } | { kind: "active_transaction"; } | { kind: "duplicate_routine"; } | { kind: "invalid_definition"; } | { kind: "stack_depth"; } | { kind: "missing_return"; } | { kind: "constant_assignment"; } | { kind: "case_missing"; } | { kind: "invalid_parameter"; } | { kind: "no_data"; } | { kind: "too_many_rows"; } | { kind: "transaction_termination"; } | { kind: "invalid_rethrow"; }
```

Query-only causes keep their semantic identity without expanding the outer tag mask.

- `invalid_role_grant`
- `invalid_window`
- `bad_copy`
- `active_transaction`
- `duplicate_routine`
- `invalid_definition`
- `stack_depth`
- `missing_return`
- `constant_assignment`
- `case_missing`
- `invalid_parameter`
- `no_data`
- `too_many_rows`
- `transaction_termination`
- `invalid_rethrow`

### `ErrorKind`

```gizlang
type ErrorKind = | { kind: "state"; } | { kind: "aborted"; } | { kind: "blocked"; } | { kind: "check"; } | { kind: "conflict"; } | { kind: "corrupt"; } | { kind: "deadlock"; } | { kind: "dependent"; } | { kind: "exists"; } | { kind: "foreign"; } | { kind: "format"; } | { kind: "internal"; } | { kind: "invalid"; } | { kind: "io"; } | { kind: "limit"; } | { kind: "lock"; } | { kind: "memory"; } | { kind: "missing"; } | { kind: "missing_column"; } | { kind: "missing_portal"; } | { kind: "missing_routine"; } | { kind: "missing_statement"; } | { kind: "null"; } | { kind: "offset"; } | { kind: "protocol"; } | { kind: "schema"; } | { kind: "stopped"; } | { kind: "syntax"; } | { kind: "trimmed"; } | { kind: "type_mismatch"; } | { kind: "unique"; } | { kind: "unsupported"; } | { kind: "unavailable"; } | { kind: "division_zero"; } | { kind: "numeric_range"; } | { kind: "cardinality"; } | { kind: "invalid_text"; } | { kind: "string_length"; } | { kind: "datetime"; } | { kind: "date_day"; } | { kind: "date_month"; } | { kind: "foreign_referenced"; } | { kind: "sequence_not_allowed"; } | { kind: "sequence_missing"; } | { kind: "sequence_currval"; } | { kind: "sequence_bound"; } | { kind: "permission"; } | { kind: "missing_object"; } | { kind: "reserved_name"; } | { kind: "duplicate_object"; } | { kind: "query"; cause: QueryErrorKind; } | { kind: "external_io"; } | { kind: "program_limit"; } | { kind: "not_ready"; } | { kind: "cancelled"; } | { kind: "missing_file"; } | { kind: "null_value"; } | { kind: "invalid_offset"; } | { kind: "sqlstate"; state: string; } | { kind: "application"; number: i64; } | { kind: "exception"; name: string; } | { kind: "kafka"; number: i64; }
```

The kind of a database error, from which its SQLSTATE and its class come.

- `state`
- `aborted`
- `blocked`
- `check`
- `conflict`
- `corrupt`
- `deadlock`
- `dependent`
- `exists`
- `foreign`
- `format`
- `internal`
- `invalid`
- `io`
- `limit`
- `lock`
- `memory`
- `missing`
- `missing_column`
- `missing_portal`
- `missing_routine`
- `missing_statement`
- `null`
- `offset`
- `protocol`
- `schema`
- `stopped`
- `syntax`
- `trimmed`
- `type_mismatch`
- `unique`
- `unsupported`
- `unavailable`
- `division_zero`
- `numeric_range`
- `cardinality`
- `invalid_text`
- `string_length`
- `datetime`
- `date_day`
- `date_month`
- `foreign_referenced`
- `sequence_not_allowed`
- `sequence_missing`
- `sequence_currval`
- `sequence_bound`
- `permission`
- `missing_object`
- `reserved_name`
- `duplicate_object`
- `query`
- `external_io`
- `program_limit`
- `not_ready`
- `cancelled`
- `missing_file`
- `null_value`
- `invalid_offset`
- `sqlstate`
- `application`
- `exception`
- `kafka`

### `FailureContext`

```gizlang
type FailureContext = { stage: string; declaration: string; field: string; expected: string; actual: string; capability: string; permission: string; }
```

Where an error happened: the stage, the declaration and field, and what was expected and found.

- `stage`: `string`
- `declaration`: `string`
- `field`: `string`
- `expected`: `string`
- `actual`: `string`
- `capability`: `string`
- `permission`: `string`

### `DbError`

```gizlang
type DbError = { code: ErrorKind; message: string; nativeCode: i64; context: Vec<FailureContext>; }
```

A database error: its kind, message, the code of the native engine that raised it, and where it happened.

- `code`: `M56.ErrorKind`
- `message`: `string`
- `nativeCode`: `i64`
- `context`: `Vec<M56.FailureContext>`

### `Diagnostic`

```gizlang
type Diagnostic = { error: DbError; stage: string; declaration: string; field: string; expected: string; actual: string; capabilities: Vec<string>; retry: string; permission: string; approval: bool; affected: Vec<string>; fixes: Vec<string>; }
```

Context is attached at a boundary; semantic error classification stays here.

- `error`: `M56.DbError`
- `stage`: `string`
- `declaration`: `string`
- `field`: `string`
- `expected`: `string`
- `actual`: `string`
- `capabilities`: `Vec<string>`
- `retry`: `string`
- `permission`: `string`
- `approval`: `bool`
- `affected`: `Vec<string>`
- `fixes`: `Vec<string>`

### `ErrorInfo`

```gizlang
type ErrorInfo = { kind: string; state: string; number: i64; name: string; }
```

The class, SQLSTATE, number and name of an error, as each protocol reports it.

- `kind`: `string`
- `state`: `string`
- `number`: `i64`
- `name`: `string`

## Functions

### `diagnostic`

```gizlang
function diagnostic(error: DbError, stage: string, declaration: string): Diagnostic
```

ERROR as a diagnostic of STAGE and DECLARATION, with the context that it carries.

Effects: fail.

### `dbError`

```gizlang
function dbError(code: ErrorKind, message: string): DbError
```

An error of the kind CODE with MESSAGE.

Effects: fail.

### `sqlFailure`

```gizlang
function sqlFailure(code: string, message: string): Result<bool, DbError>
```

The failed result of a statement with the SQLSTATE CODE.

Effects: fail.

### `contextual`

```gizlang
function contextual(error: DbError, context: FailureContext): DbError
```

ERROR with CONTEXT added (at most 16).

Effects: fail.

### `withCleanup`

```gizlang
function withCleanup(error: DbError, cleanup: string): DbError
```

A failure whose cleanup also failed keeps its class and native cause; the message names both.

Effects: fail.

### `afterCleanup`

```gizlang
function afterCleanup<T>(error: DbError, cleanup: Result<T, DbError>): DbError
```

ERROR after a cleanup that gave CLEANUP: the error, and the cleanup's failure in its message when it failed.

### `ioError`

```gizlang
function ioError(error: IoError): DbError
```

One database boundary preserves resource refusal, stale ownership and I/O causes.

Effects: fail, io.

### `ioFailure`

```gizlang
function ioFailure(action: string, error: IoError): DbError
```

An I/O failure of `action` ("open PATH"), with its native cause.

Effects: fail, io.

### `fromIo`

```gizlang
function fromIo<T>(result: Result<T, IoError>): Result<T, DbError>
```

RESULT with its system error as a database error.

### `errorInfo`

```gizlang
function errorInfo(error: DbError): ErrorInfo
```

Exhaustive projection from typed causes; protocol text never decides a semantic failure.

### `semanticKind`

```gizlang
function semanticKind(error: DbError): string
```

The class of the error ("constraint", "missing", ...), as errorInfo gives it.

### `noRelation`

```gizlang
function noRelation(name: string): DbError
```

42P01: no relation NAME.

Effects: fail.

### `noColumn`

```gizlang
function noColumn(column: string, relation: string): DbError
```

42703: no column COLUMN in relation RELATION.

Effects: fail.

### `relationExists`

```gizlang
function relationExists(name: string): DbError
```

42P07: a relation NAME is there already.

Effects: fail.

### `fromMessage`

```gizlang
function fromMessage<T>(result: Result<T, string>, code: ErrorKind): Result<T, DbError>
```

RESULT with its text error as a database error of the kind CODE.

### `errorCode`

```gizlang
function errorCode(error: DbError): string
```

Diagnostic spelling only; no decision reconstructs a kind from this text.

Effects: fail.

### `memoryError`

```gizlang
function memoryError(message: string): DbError
```

A statement whose working memory or result cannot fit its grant: out of memory (SQLSTATE 53200).

Effects: fail.

### `detailed`

```gizlang
function detailed(code: ErrorKind, message: string, detail: string): DbError
```

An error with PostgreSQL's DETAIL line (the ErrorResponse D field; pg_input_error_info's detail).

Effects: fail.

### `errorDetail`

```gizlang
function errorDetail(error: DbError): string
```

The DETAIL line of an error, "" for none.

Effects: fail.

### `hinted`

```gizlang
function hinted(error: DbError, hint: string): DbError
```

An error with PostgreSQL's HINT line (the ErrorResponse H field).

Effects: fail.

### `errorHint`

```gizlang
function errorHint(error: DbError): string
```

The HINT line of an error, "" for none.

Effects: fail.

### `positioned`

```gizlang
function positioned(error: DbError, at: i64): DbError
```

An error at byte offset AT of the statement text (the ErrorResponse P field, from which psql draws its LINE).

Effects: fail.

### `errorPosition`

```gizlang
function errorPosition(error: DbError): i64
```

The byte offset an error names in the statement text, -1 for none.

Effects: fail.

