@unthrown/prisma
@unthrown/prisma
Classes
DriverError
Defined in: packages/prisma/src/index.ts:61
Any other query failure: connection drops, timeouts, unmapped P-codes, driver-level errors.
Remarks
Prisma validation errors land here too. Arguably a malformed query is a programmer bug rather than an anticipated outcome; triage it further at the call site if the distinction matters to you.
Extends
TaggedErrorInstance<"DriverError", {cause:unknown; }>
Constructors
Constructor
new DriverError(args): DriverError;Defined in: packages/core/dist/index.d.mts:1444
Parameters
| Parameter | Type |
|---|---|
args | object & object |
Returns
Inherited from
TaggedError("DriverError")<{ cause: unknown }>.constructorProperties
ForeignKeyViolation
Defined in: packages/prisma/src/index.ts:44
A foreign key constraint was violated (Prisma error P2003).
Extends
TaggedErrorInstance<"ForeignKeyViolation", {cause:unknown; }>
Constructors
Constructor
new ForeignKeyViolation(args): ForeignKeyViolation;Defined in: packages/core/dist/index.d.mts:1444
Parameters
| Parameter | Type |
|---|---|
args | object & object |
Returns
Inherited from
TaggedError("ForeignKeyViolation")<{ cause: unknown }>.constructorProperties
RecordNotFound
Defined in: packages/prisma/src/index.ts:50
A record required by the operation does not exist (Prisma error P2025) — the missing row of a findUniqueOrThrow, update, or delete.
Extends
TaggedErrorInstance<"RecordNotFound", {cause:unknown; }>
Constructors
Constructor
new RecordNotFound(args): RecordNotFound;Defined in: packages/core/dist/index.d.mts:1444
Parameters
| Parameter | Type |
|---|---|
args | object & object |
Returns
Inherited from
TaggedError("RecordNotFound")<{ cause: unknown }>.constructorProperties
UniqueConstraintViolation
Defined in: packages/prisma/src/index.ts:38
A unique constraint was violated (Prisma error P2002).
Remarks
fields carries the offending column set from the error's meta.target (empty when the driver does not report it).
Extends
TaggedErrorInstance<"UniqueConstraintViolation", {cause:unknown;fields: readonlystring[]; }>
Constructors
Constructor
new UniqueConstraintViolation(args): UniqueConstraintViolation;Defined in: packages/core/dist/index.d.mts:1444
Parameters
| Parameter | Type |
|---|---|
args | object & object |
Returns
Inherited from
TaggedError("UniqueConstraintViolation")<{
fields: readonly string[];
cause: unknown;
}>.constructorProperties
| Property | Modifier | Type | Inherited from | Defined in |
|---|---|---|---|---|
_tag | readonly | "UniqueConstraintViolation" | TaggedError("UniqueConstraintViolation")._tag | packages/core/dist/index.d.mts:1423 |
cause | public | unknown | TaggedError("UniqueConstraintViolation").cause | node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.error.d.ts:24 |
fields | readonly | readonly string[] | TaggedError("UniqueConstraintViolation").fields | packages/prisma/src/index.ts:39 |
message | public | string | TaggedError("UniqueConstraintViolation").message | node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1075 |
name | public | string | TaggedError("UniqueConstraintViolation").name | node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1074 |
stack? | public | string | TaggedError("UniqueConstraintViolation").stack | node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1076 |
Type Aliases
CursorPaginationMeta
type CursorPaginationMeta = object &
| {
endCursor: string;
startCursor: string;
}
| {
endCursor: null;
startCursor: null;
};Defined in: packages/prisma/src/pagination.ts:20
The page metadata of withCursor.
Type Declaration
| Name | Type | Defined in |
|---|---|---|
hasNextPage | boolean | packages/prisma/src/pagination.ts:22 |
hasPreviousPage | boolean | packages/prisma/src/pagination.ts:21 |
Remarks
startCursor / endCursor are the cursors of the page's boundary rows, so they are null together exactly when the page is empty — checking one narrows the other. They are deliberately NOT coupled to the flags: the last page has hasNextPage: false with a non-null endCursor, and an empty page past the end has hasPreviousPage: true with a null startCursor.
CursorPaginationOptions
type CursorPaginationOptions<Row, Cursor> = object &
| {
before?: string;
limit: number;
}
| {
before?: never;
limit: null;
};Defined in: packages/prisma/src/pagination.ts:44
Options of withCursor, in the style of prisma-extension-pagination.
Type Declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
after? | string | An opaque cursor: results strictly AFTER this record. | packages/prisma/src/pagination.ts:46 |
getCursor()? | (row) => string | Serialize a row into an opaque cursor. Defaults to String(row.id). | packages/prisma/src/pagination.ts:48 |
parseCursor()? | (cursor) => Cursor | Parse an opaque cursor back into the model's cursor input. | packages/prisma/src/pagination.ts:50 |
Type Parameters
| Type Parameter | Description |
|---|---|
Row | the (selection-narrowed) result row type. |
Cursor | the model's cursor input (its unique-where shape). |
Remarks
limit: null returns everything (from the after cursor when given). Combining limit: null with before is a compile error — "everything before the cursor, backwards, unbounded" is not something Prisma's negative take can express.
The default cursor is the record's id field, serialized with String and parsed back to a number when it is all digits (autoincrement ids) — a bigint once it exceeds Number.MAX_SAFE_INTEGER, so BigInt ids never lose precision — or kept as a string otherwise (uuid / cuid ids). Provide getCursor / parseCursor for composite keys, or when the selection omits id.
CursorPaginator
type CursorPaginator<Results, Cursor> = object;Defined in: packages/prisma/src/index.ts:202
What tryPaginate returns: a builder holding the query, consumed by withCursor.
Type Parameters
| Type Parameter | Description |
|---|---|
Results extends readonly unknown[] | the (selection-narrowed) findMany payload. |
Cursor | the model's cursor input (its unique-where shape). |
Properties
| Property | Modifier | Type | Description | Defined in |
|---|---|---|---|---|
withCursor | readonly | (options) => AsyncResult<[Results, CursorPaginationMeta], DriverError> | Run the paginated query: the page and its metadata, or a DriverError. | packages/prisma/src/index.ts:207 |
PrismaQueryError
type PrismaQueryError =
| UniqueConstraintViolation
| ForeignKeyViolation
| RecordNotFound
| DriverError;Defined in: packages/prisma/src/index.ts:71
The full union of tagged errors a Prisma query can surface.
Remarks
This is the RUNTIME-side union: qualifyPrismaError maps into it. Each try* method narrows the static type to the codes its operation can actually hit (a read is typed DriverError only).
TransactionIsolationLevel
type TransactionIsolationLevel =
| "ReadUncommitted"
| "ReadCommitted"
| "RepeatableRead"
| "Snapshot"
| "Serializable";Defined in: packages/prisma/src/index.ts:188
The isolation levels Prisma accepts across databases, as a closed union.
Remarks
The schema-derived Prisma.TransactionIsolationLevel of a generated client is narrower (it lists only what YOUR database supports), but a shareable extension cannot name a generated type — this union at least rejects typos at compile time; a level your database does not support still fails at runtime as a DriverError.
Variables
unthrownPrisma
const unthrownPrisma: (client) => PrismaClientExtends<InternalArgs<{
}, {
$allModels: {
tryAggregate: AsyncResult<Result<T, A, "aggregate">, DriverError>;
tryCount: AsyncResult<Result<T, A, "count">, DriverError>;
tryCreate: AsyncResult<Result<T, A, "create">, CreateError>;
tryCreateMany: AsyncResult<Result<T, A, "createMany">, CreateError>;
tryCreateManyAndReturn: AsyncResult<Result<T, A, "createManyAndReturn">, CreateError>;
tryDelete: AsyncResult<Result<T, A, "delete">, DeleteError>;
tryDeleteMany: AsyncResult<Result<T, A, "deleteMany">, DeleteManyError>;
tryFindFirst: AsyncResult<Result<T, A, "findFirst">, DriverError>;
tryFindFirstOrThrow: AsyncResult<Result<T, A, "findFirstOrThrow">, RecordNotFound | DriverError>;
tryFindMany: AsyncResult<Result<T, A, "findMany">, DriverError>;
tryFindUnique: AsyncResult<Result<T, A, "findUnique">, DriverError>;
tryFindUniqueOrThrow: AsyncResult<Result<T, A, "findUniqueOrThrow">, RecordNotFound | DriverError>;
tryGroupBy: AsyncResult<Result<T, A, "groupBy">, DriverError>;
tryPaginate: CursorPaginator<Result<T, A, "findMany">, NonNullable<Args<T, "findMany">["cursor"]>>;
tryUpdate: AsyncResult<Result<T, A, "update">, UpdateError>;
tryUpdateMany: AsyncResult<Result<T, A, "updateMany">, UpdateManyError>;
tryUpdateManyAndReturn: AsyncResult<Result<T, A, "updateManyAndReturn">, UpdateManyError>;
tryUpsert: AsyncResult<Result<T, A, "upsert">, UpsertError>;
};
}, {
}, {
$tryTransaction: AsyncResult<T, PrismaQueryError | E>;
}>>;Defined in: packages/prisma/src/index.ts:244
The Prisma Client extension. Apply it with $extends to add the try* methods to every model delegate, and $tryTransaction to the client.
Parameters
| Parameter | Type |
|---|---|
client | any |
Returns
PrismaClientExtends<InternalArgs<{ }, { $allModels: { tryAggregate: AsyncResult<Result<T, A, "aggregate">, DriverError>; tryCount: AsyncResult<Result<T, A, "count">, DriverError>; tryCreate: AsyncResult<Result<T, A, "create">, CreateError>; tryCreateMany: AsyncResult<Result<T, A, "createMany">, CreateError>; tryCreateManyAndReturn: AsyncResult<Result<T, A, "createManyAndReturn">, CreateError>; tryDelete: AsyncResult<Result<T, A, "delete">, DeleteError>; tryDeleteMany: AsyncResult<Result<T, A, "deleteMany">, DeleteManyError>; tryFindFirst: AsyncResult<Result<T, A, "findFirst">, DriverError>; tryFindFirstOrThrow: AsyncResult<Result<T, A, "findFirstOrThrow">, RecordNotFound | DriverError>; tryFindMany: AsyncResult<Result<T, A, "findMany">, DriverError>; tryFindUnique: AsyncResult<Result<T, A, "findUnique">, DriverError>; tryFindUniqueOrThrow: AsyncResult<Result<T, A, "findUniqueOrThrow">, RecordNotFound | DriverError>; tryGroupBy: AsyncResult<Result<T, A, "groupBy">, DriverError>; tryPaginate: CursorPaginator<Result<T, A, "findMany">, NonNullable<Args<T, "findMany">["cursor"]>>; tryUpdate: AsyncResult<Result<T, A, "update">, UpdateError>; tryUpdateMany: AsyncResult<Result<T, A, "updateMany">, UpdateManyError>; tryUpdateManyAndReturn: AsyncResult<Result<T, A, "updateManyAndReturn">, UpdateManyError>; tryUpsert: AsyncResult<Result<T, A, "upsert">, UpsertError>; }; }, { }, { $tryTransaction: AsyncResult<T, PrismaQueryError | E>; }>>
Remarks
Typing follows Prisma's documented $allModels pattern: this: T binds the concrete delegate, Prisma.Exact checks args, and Prisma.Result computes the payload — so select / include inference survives the wrap.
Example
import { PrismaClient } from "./generated/prisma/client.ts";
import { unthrownPrisma } from "@unthrown/prisma";
const db = new PrismaClient({ adapter }).$extends(unthrownPrisma);
const users = db.user.tryFindMany({ select: { id: true } });
// ^? AsyncResult<{ id: number }[], DriverError>Functions
qualifyPrismaError()
function qualifyPrismaError(cause): PrismaQueryError;Defined in: packages/prisma/src/index.ts:121
Qualify a Prisma rejection into a tagged error — the runtime half of the bridge.
Parameters
| Parameter | Type | Description |
|---|---|---|
cause | unknown | the rejected value from a Prisma query. |
Returns
Remarks
Recognized P-codes map to their dedicated errors (P2002 → UniqueConstraintViolation, P2003 → ForeignKeyViolation, P2025 → RecordNotFound); everything else — including non-Prisma causes — folds into DriverError with the cause preserved.