@prisma-next/sql-errors 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/dist/exports/index.d.ts +45 -0
- package/dist/exports/index.js +46 -0
- package/dist/exports/index.js.map +1 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# @prisma-next/sql-errors
|
|
2
|
+
|
|
3
|
+
SQL-normalized driver error types for Prisma Next.
|
|
4
|
+
|
|
5
|
+
## Package Classification
|
|
6
|
+
|
|
7
|
+
- **Domain**: sql
|
|
8
|
+
- **Layer**: core
|
|
9
|
+
- **Plane**: shared
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
This package provides normalized error classes for SQL driver errors. These errors are shared across both migration-plane and runtime-plane code, allowing consistent error handling regardless of which driver is being used.
|
|
14
|
+
|
|
15
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
Normalize driver-specific errors (e.g., Postgres `pg` errors) into well-typed, SQL-family error classes that can be handled deterministically by migration runners, CLI commands, and other downstream systems.
|
|
18
|
+
|
|
19
|
+
## Responsibilities
|
|
20
|
+
|
|
21
|
+
- **Error Types**: Define `SqlQueryError` and `SqlConnectionError` classes
|
|
22
|
+
- **Type Predicates**: Provide `.is()` methods for safe error checking without `instanceof`
|
|
23
|
+
- **Stack Trace Preservation**: Preserve original error stack traces via ES2022 `Error.cause`
|
|
24
|
+
|
|
25
|
+
## Error Classes
|
|
26
|
+
|
|
27
|
+
### SqlQueryError
|
|
28
|
+
|
|
29
|
+
Represents query-related failures:
|
|
30
|
+
- Syntax errors
|
|
31
|
+
- Constraint violations
|
|
32
|
+
- Permission errors
|
|
33
|
+
- Other SQL execution errors
|
|
34
|
+
|
|
35
|
+
**Fields**:
|
|
36
|
+
- `kind`: `'sql_query'` (discriminator)
|
|
37
|
+
- `sqlState`: Postgres SQLSTATE code (e.g., `'23505'`)
|
|
38
|
+
- `constraint`: Constraint name if applicable
|
|
39
|
+
- `table`: Table name if applicable
|
|
40
|
+
- `column`: Column name if applicable
|
|
41
|
+
- `detail`: Additional detail from database
|
|
42
|
+
|
|
43
|
+
### SqlConnectionError
|
|
44
|
+
|
|
45
|
+
Represents connection-related failures:
|
|
46
|
+
- Connection timeouts
|
|
47
|
+
- Connection resets
|
|
48
|
+
- Connection refused
|
|
49
|
+
- Other connectivity issues
|
|
50
|
+
|
|
51
|
+
**Fields**:
|
|
52
|
+
- `kind`: `'sql_connection'` (discriminator)
|
|
53
|
+
- `transient`: Whether retry might succeed
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { SqlQueryError, SqlConnectionError } from '@prisma-next/sql-errors';
|
|
59
|
+
|
|
60
|
+
// Check error type using type predicate (recommended)
|
|
61
|
+
if (SqlQueryError.is(error)) {
|
|
62
|
+
console.log('SQLSTATE:', error.sqlState);
|
|
63
|
+
console.log('Constraint:', error.constraint);
|
|
64
|
+
console.log('Original stack:', error.cause?.stack);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Create normalized error with original error preserved
|
|
68
|
+
const normalized = new SqlQueryError('Query failed', {
|
|
69
|
+
cause: originalError,
|
|
70
|
+
sqlState: '23505',
|
|
71
|
+
constraint: 'user_email_unique',
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Architecture
|
|
76
|
+
|
|
77
|
+
This package is in the **shared plane**, meaning it can be imported by both migration-plane and runtime-plane packages. This allows drivers (runtime plane) and migration runners (migration plane) to use the same error types.
|
|
78
|
+
|
|
79
|
+
## Related Documentation
|
|
80
|
+
|
|
81
|
+
- `docs/architecture docs/subsystems/5. Adapters & Targets.md`: Driver architecture
|
|
82
|
+
- `docs/Error Handling.md`: Error handling patterns
|
|
83
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
interface SqlDriverError<Kind extends string> {
|
|
2
|
+
readonly kind: Kind;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* SQL query error for query-related failures (syntax errors, constraint violations, permissions).
|
|
6
|
+
*/
|
|
7
|
+
declare class SqlQueryError extends Error implements SqlDriverError<'sql_query'> {
|
|
8
|
+
static readonly ERROR_NAME: "SqlQueryError";
|
|
9
|
+
readonly kind: "sql_query";
|
|
10
|
+
readonly sqlState: string | undefined;
|
|
11
|
+
readonly constraint: string | undefined;
|
|
12
|
+
readonly table: string | undefined;
|
|
13
|
+
readonly column: string | undefined;
|
|
14
|
+
readonly detail: string | undefined;
|
|
15
|
+
constructor(message: string, options?: {
|
|
16
|
+
readonly cause?: Error;
|
|
17
|
+
readonly sqlState?: string;
|
|
18
|
+
readonly constraint?: string;
|
|
19
|
+
readonly table?: string;
|
|
20
|
+
readonly column?: string;
|
|
21
|
+
readonly detail?: string;
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* Type predicate to check if an error is a SqlQueryError.
|
|
25
|
+
*/
|
|
26
|
+
static is(error: unknown): error is SqlQueryError;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* SQL connection error (timeouts, connection resets, etc.).
|
|
30
|
+
*/
|
|
31
|
+
declare class SqlConnectionError extends Error implements SqlDriverError<'sql_connection'> {
|
|
32
|
+
static readonly ERROR_NAME: "SqlConnectionError";
|
|
33
|
+
readonly kind: "sql_connection";
|
|
34
|
+
readonly transient: boolean | undefined;
|
|
35
|
+
constructor(message: string, options?: {
|
|
36
|
+
readonly cause?: Error;
|
|
37
|
+
readonly transient?: boolean;
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Type predicate to check if an error is a SqlConnectionError.
|
|
41
|
+
*/
|
|
42
|
+
static is(error: unknown): error is SqlConnectionError;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { SqlConnectionError, SqlQueryError };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var SqlQueryError = class _SqlQueryError extends Error {
|
|
3
|
+
static ERROR_NAME = "SqlQueryError";
|
|
4
|
+
kind = "sql_query";
|
|
5
|
+
sqlState;
|
|
6
|
+
constraint;
|
|
7
|
+
table;
|
|
8
|
+
column;
|
|
9
|
+
detail;
|
|
10
|
+
constructor(message, options) {
|
|
11
|
+
super(message, { cause: options?.cause });
|
|
12
|
+
this.name = _SqlQueryError.ERROR_NAME;
|
|
13
|
+
this.sqlState = options?.sqlState;
|
|
14
|
+
this.constraint = options?.constraint;
|
|
15
|
+
this.table = options?.table;
|
|
16
|
+
this.column = options?.column;
|
|
17
|
+
this.detail = options?.detail;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Type predicate to check if an error is a SqlQueryError.
|
|
21
|
+
*/
|
|
22
|
+
static is(error) {
|
|
23
|
+
return typeof error === "object" && error !== null && Object.hasOwn(error, "kind") && error.kind === "sql_query";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var SqlConnectionError = class _SqlConnectionError extends Error {
|
|
27
|
+
static ERROR_NAME = "SqlConnectionError";
|
|
28
|
+
kind = "sql_connection";
|
|
29
|
+
transient;
|
|
30
|
+
constructor(message, options) {
|
|
31
|
+
super(message, { cause: options?.cause });
|
|
32
|
+
this.name = _SqlConnectionError.ERROR_NAME;
|
|
33
|
+
this.transient = options?.transient;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Type predicate to check if an error is a SqlConnectionError.
|
|
37
|
+
*/
|
|
38
|
+
static is(error) {
|
|
39
|
+
return typeof error === "object" && error !== null && Object.hasOwn(error, "kind") && error.kind === "sql_connection";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
export {
|
|
43
|
+
SqlConnectionError,
|
|
44
|
+
SqlQueryError
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/errors.ts"],"sourcesContent":["export interface SqlDriverError<Kind extends string> {\n readonly kind: Kind;\n}\n/**\n * SQL query error for query-related failures (syntax errors, constraint violations, permissions).\n */\nexport class SqlQueryError extends Error implements SqlDriverError<'sql_query'> {\n static readonly ERROR_NAME = 'SqlQueryError' as const;\n readonly kind = 'sql_query' as const;\n readonly sqlState: string | undefined;\n readonly constraint: string | undefined;\n readonly table: string | undefined;\n readonly column: string | undefined;\n readonly detail: string | undefined;\n\n constructor(\n message: string,\n options?: {\n readonly cause?: Error;\n readonly sqlState?: string;\n readonly constraint?: string;\n readonly table?: string;\n readonly column?: string;\n readonly detail?: string;\n },\n ) {\n super(message, { cause: options?.cause });\n this.name = SqlQueryError.ERROR_NAME;\n this.sqlState = options?.sqlState;\n this.constraint = options?.constraint;\n this.table = options?.table;\n this.column = options?.column;\n this.detail = options?.detail;\n }\n\n /**\n * Type predicate to check if an error is a SqlQueryError.\n */\n static is(error: unknown): error is SqlQueryError {\n return (\n typeof error === 'object' &&\n error !== null &&\n Object.hasOwn(error, 'kind') &&\n (error as { kind: unknown }).kind === 'sql_query'\n );\n }\n}\n\n/**\n * SQL connection error (timeouts, connection resets, etc.).\n */\nexport class SqlConnectionError extends Error implements SqlDriverError<'sql_connection'> {\n static readonly ERROR_NAME = 'SqlConnectionError' as const;\n readonly kind = 'sql_connection' as const;\n readonly transient: boolean | undefined;\n\n constructor(\n message: string,\n options?: {\n readonly cause?: Error;\n readonly transient?: boolean;\n },\n ) {\n super(message, { cause: options?.cause });\n this.name = SqlConnectionError.ERROR_NAME;\n this.transient = options?.transient;\n }\n\n /**\n * Type predicate to check if an error is a SqlConnectionError.\n */\n static is(error: unknown): error is SqlConnectionError {\n return (\n typeof error === 'object' &&\n error !== null &&\n Object.hasOwn(error, 'kind') &&\n (error as { kind: unknown }).kind === 'sql_connection'\n );\n }\n}\n"],"mappings":";AAMO,IAAM,gBAAN,MAAM,uBAAsB,MAA6C;AAAA,EAC9E,OAAgB,aAAa;AAAA,EACpB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,SACA,SAQA;AACA,UAAM,SAAS,EAAE,OAAO,SAAS,MAAM,CAAC;AACxC,SAAK,OAAO,eAAc;AAC1B,SAAK,WAAW,SAAS;AACzB,SAAK,aAAa,SAAS;AAC3B,SAAK,QAAQ,SAAS;AACtB,SAAK,SAAS,SAAS;AACvB,SAAK,SAAS,SAAS;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,GAAG,OAAwC;AAChD,WACE,OAAO,UAAU,YACjB,UAAU,QACV,OAAO,OAAO,OAAO,MAAM,KAC1B,MAA4B,SAAS;AAAA,EAE1C;AACF;AAKO,IAAM,qBAAN,MAAM,4BAA2B,MAAkD;AAAA,EACxF,OAAgB,aAAa;AAAA,EACpB,OAAO;AAAA,EACP;AAAA,EAET,YACE,SACA,SAIA;AACA,UAAM,SAAS,EAAE,OAAO,SAAS,MAAM,CAAC;AACxC,SAAK,OAAO,oBAAmB;AAC/B,SAAK,YAAY,SAAS;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,GAAG,OAA6C;AACrD,WACE,OAAO,UAAU,YACjB,UAAU,QACV,OAAO,OAAO,OAAO,MAAM,KAC1B,MAA4B,SAAS;AAAA,EAE1C;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prisma-next/sql-errors",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"description": "Normalized SQL driver error types for Prisma Next",
|
|
7
|
+
"dependencies": {},
|
|
8
|
+
"devDependencies": {
|
|
9
|
+
"@vitest/coverage-v8": "^2.1.1",
|
|
10
|
+
"tsup": "^8.3.0",
|
|
11
|
+
"typescript": "^5.9.3",
|
|
12
|
+
"vitest": "^4.0.16",
|
|
13
|
+
"@prisma-next/test-utils": "0.0.1"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/exports/index.d.ts",
|
|
21
|
+
"import": "./dist/exports/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsup --config tsup.config.ts",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:coverage": "vitest run --coverage",
|
|
28
|
+
"typecheck": "tsc --project tsconfig.json --noEmit",
|
|
29
|
+
"lint": "biome check . --config-path ../../../../biome.json --error-on-warnings",
|
|
30
|
+
"lint:fix": "biome check --write . --config-path ../../../../biome.json",
|
|
31
|
+
"lint:fix:unsafe": "biome check --write --unsafe . --config-path ../../../../biome.json",
|
|
32
|
+
"clean": "node ../../../../scripts/clean.mjs"
|
|
33
|
+
}
|
|
34
|
+
}
|