@rexezuge/errors 1.0.1 → 1.0.3
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 +75 -0
- package/dist/BadGatewayError.js.map +1 -1
- package/dist/BadRequestError.js.map +1 -1
- package/dist/CATALOG.js.map +1 -1
- package/dist/ConflictError.js.map +1 -1
- package/dist/DatabaseError.js.map +1 -1
- package/dist/ErrorResponse.js.map +1 -1
- package/dist/ForbiddenError.js.map +1 -1
- package/dist/HttpServiceError.js.map +1 -1
- package/dist/InternalServerError.js.map +1 -1
- package/dist/MethodNotAllowedError.js.map +1 -1
- package/dist/NotFoundError.js.map +1 -1
- package/dist/NotImplementedError.js.map +1 -1
- package/dist/OutcomeError.js.map +1 -1
- package/dist/PayloadTooLargeError.js.map +1 -1
- package/dist/PreconditionFailedError.js.map +1 -1
- package/dist/RateLimitedError.js.map +1 -1
- package/dist/ServiceError.js.map +1 -1
- package/dist/ServiceUnavailableError.js.map +1 -1
- package/dist/UnauthorizedError.js.map +1 -1
- package/dist/UnsupportedMediaTypeError.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# @rexezuge/errors
|
|
2
|
+
|
|
3
|
+
Catalog-driven HTTP/service error taxonomy with retry markers and wire envelopes for the Rexezuge-CloudflareWorkers family.
|
|
4
|
+
|
|
5
|
+
Zero dependencies. Every boundary in the family (route handlers, middleware, background tasks) branches on `instanceof ServiceError`, so this package sits at the bottom of the dependency graph: `d1`, `identity`, and `web` all import it.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @rexezuge/errors
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. The taxonomy
|
|
14
|
+
|
|
15
|
+
`ServiceError` is the abstract root. Status, machine `type`, `retryable`, and `expose` are public fields fixed at construction — callers read them far more often than they are written.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { NotFoundError, ServiceError } from '@rexezuge/errors';
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
await loadFile(id);
|
|
22
|
+
} catch (error: unknown) {
|
|
23
|
+
const normalized = ServiceError.from(error); // ServiceError passes through; anything else becomes a 500
|
|
24
|
+
return Response.json(normalized.toErrorResponse().body, { status: normalized.status });
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`toErrorResponse()` returns `{ status, body }` in the family envelope `{ Exception: { Type, Message } }`. A non-exposing error (5xx) has its message substituted with a generic one — the real message is for operators, never clients.
|
|
29
|
+
|
|
30
|
+
## 2. Status classes
|
|
31
|
+
|
|
32
|
+
One class per row of `CATALOG`, so a status can never disagree with its code or default message:
|
|
33
|
+
|
|
34
|
+
| Class | Status | Exposes message |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| `BadRequestError` | 400 | yes |
|
|
37
|
+
| `UnauthorizedError` | 401 | yes |
|
|
38
|
+
| `ForbiddenError` | 403 | yes |
|
|
39
|
+
| `NotFoundError` | 404 | yes |
|
|
40
|
+
| `MethodNotAllowedError` | 405 | yes |
|
|
41
|
+
| `ConflictError` | 409 | yes |
|
|
42
|
+
| `PreconditionFailedError` | 412 | yes |
|
|
43
|
+
| `PayloadTooLargeError` | 413 | yes |
|
|
44
|
+
| `UnsupportedMediaTypeError` | 415 | yes |
|
|
45
|
+
| `RateLimitedError` | 429 | yes |
|
|
46
|
+
| `InternalServerError` | 500 | no |
|
|
47
|
+
| `NotImplementedError` | 501 | no |
|
|
48
|
+
| `BadGatewayError` | 502 | no |
|
|
49
|
+
| `ServiceUnavailableError` | 503 | yes |
|
|
50
|
+
| `DatabaseError` | 502 | no |
|
|
51
|
+
|
|
52
|
+
`HttpServiceError` is the generic carrier when only a catalog entry is needed. `DatabaseError` carries the D1 classifier's verdict in its `retryable` flag.
|
|
53
|
+
|
|
54
|
+
## 3. Outcome errors
|
|
55
|
+
|
|
56
|
+
When only the throwing code knows whether a retry could help (OAuth grant revoked vs. provider throttling), it says so explicitly:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { NonRetryableError, RetryableError } from '@rexezuge/errors';
|
|
60
|
+
|
|
61
|
+
throw new RetryableError('Provider throttled us'); // 502, retryable
|
|
62
|
+
throw new NonRetryableError('Grant revoked'); // 400, not retryable
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`ProviderApiRetryableError` / `ProviderApiNonRetryableError` and `OAuth2TokenRetryableError` / `OAuth2TokenNonRetryableError` are the domain aliases. Subclasses must genuinely `extend` — an `implements` breaks the `instanceof` chain and masks typed errors as generic 500s.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Verifying this package
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pnpm --filter @rexezuge/errors exec tsc -p tsconfig.json
|
|
73
|
+
pnpm --filter @rexezuge/errors typecheck
|
|
74
|
+
pnpm --filter @rexezuge/errors test
|
|
75
|
+
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BadGatewayError.js","sourceRoot":"","sources":["../src/BadGatewayError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,eAAgB,SAAQ,gBAA8B;IAC1D,YAAY,OAAgB;QAC1B,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"BadGatewayError.js","sourceRoot":"","sources":["../src/BadGatewayError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,eAAgB,SAAQ,gBAA8B;IAC1D,YAAY,OAAgB;QAC1B,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,OAAO,EAAE,eAAe,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 502 — an upstream dependency answered invalidly. Pair with `retryable: true`\n * when the upstream is known to recover on its own.\n */\nclass BadGatewayError extends HttpServiceError<'badGateway'> {\n constructor(message?: string) {\n super('badGateway', message);\n }\n}\n\nexport { BadGatewayError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BadRequestError.js","sourceRoot":"","sources":["../src/BadRequestError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,eAAgB,SAAQ,gBAA8B;IAC1D,YAAY,OAAgB;QAC1B,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"BadRequestError.js","sourceRoot":"","sources":["../src/BadRequestError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,eAAgB,SAAQ,gBAA8B;IAC1D,YAAY,OAAgB;QAC1B,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,OAAO,EAAE,eAAe,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 400 — malformed or missing input. Retrying without a change always fails.\n */\nclass BadRequestError extends HttpServiceError<'badRequest'> {\n constructor(message?: string) {\n super('badRequest', message);\n }\n}\n\nexport { BadRequestError };\n"]}
|
package/dist/CATALOG.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CATALOG.js","sourceRoot":"","sources":["../src/CATALOG.ts"],"names":[],"mappings":"AAmBA,MAAM,OAAO,GAAG;IACd,UAAU,EAAE;QACV,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,aAAa;QACnB,cAAc,EAAE,yEAAyE;QACzF,MAAM,EAAE,IAAI;KACb;IACD,YAAY,EAAE;QACZ,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,cAAc;QACpB,cAAc,EAAE,yEAAyE;QACzF,MAAM,EAAE,IAAI;KACb;IACD,SAAS,EAAE;QACT,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,WAAW;QACjB,cAAc,EAAE,oDAAoD;QACpE,MAAM,EAAE,IAAI;KACb;IACD,QAAQ,EAAE;QACR,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,WAAW;QACjB,cAAc,EAAE,uCAAuC;QACvD,MAAM,EAAE,IAAI;KACb;IACD,gBAAgB,EAAE;QAChB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,oBAAoB;QAC1B,cAAc,EAAE,wDAAwD;QACxE,MAAM,EAAE,IAAI;KACb;IACD,QAAQ,EAAE;QACR,sEAAsE;QACtE,sEAAsE;QACtE,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,UAAU;QAChB,cAAc,EAAE,+DAA+D;QAC/E,MAAM,EAAE,IAAI;KACb;IACD,kBAAkB,EAAE;QAClB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,qBAAqB;QAC3B,cAAc,EAAE,yCAAyC;QACzD,MAAM,EAAE,IAAI;KACb;IACD,eAAe,EAAE;QACf,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,mBAAmB;QACzB,cAAc,EAAE,sEAAsE;QACtF,MAAM,EAAE,IAAI;KACb;IACD,oBAAoB,EAAE;QACpB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,wBAAwB;QAC9B,cAAc,EAAE,+DAA+D;QAC/E,MAAM,EAAE,IAAI;KACb;IACD,WAAW,EAAE;QACX,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,cAAc;QACpB,cAAc,EAAE,gDAAgD;QAChE,MAAM,EAAE,IAAI;KACb;IACD,mBAAmB,EAAE;QACnB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,uBAAuB;QAC7B,cAAc,EAAE,mFAAmF;QACnG,MAAM,EAAE,KAAK;KACd;IACD,cAAc,EAAE;QACd,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,iBAAiB;QACvB,cAAc,EAAE,gFAAgF;QAChG,MAAM,EAAE,KAAK;KACd;IACD,uEAAuE;IACvE,+DAA+D;IAC/D,UAAU,EAAE;QACV,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,aAAa;QACnB,cAAc,EAAE,mEAAmE;QACnF,MAAM,EAAE,KAAK;KACd;IACD,kBAAkB,EAAE;QAClB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,qBAAqB;QAC3B,cAAc,EAAE,6EAA6E;QAC7F,MAAM,EAAE,IAAI;KACb;CACqD,CAAC;AAIzD,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"CATALOG.js","sourceRoot":"","sources":["../src/CATALOG.ts"],"names":[],"mappings":"AAmBA,MAAM,OAAO,GAAG;IACd,UAAU,EAAE;QACV,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,aAAa;QACnB,cAAc,EAAE,yEAAyE;QACzF,MAAM,EAAE,IAAI;KACb;IACD,YAAY,EAAE;QACZ,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,cAAc;QACpB,cAAc,EAAE,yEAAyE;QACzF,MAAM,EAAE,IAAI;KACb;IACD,SAAS,EAAE;QACT,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,WAAW;QACjB,cAAc,EAAE,oDAAoD;QACpE,MAAM,EAAE,IAAI;KACb;IACD,QAAQ,EAAE;QACR,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,WAAW;QACjB,cAAc,EAAE,uCAAuC;QACvD,MAAM,EAAE,IAAI;KACb;IACD,gBAAgB,EAAE;QAChB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,oBAAoB;QAC1B,cAAc,EAAE,wDAAwD;QACxE,MAAM,EAAE,IAAI;KACb;IACD,QAAQ,EAAE;QACR,sEAAsE;QACtE,sEAAsE;QACtE,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,UAAU;QAChB,cAAc,EAAE,+DAA+D;QAC/E,MAAM,EAAE,IAAI;KACb;IACD,kBAAkB,EAAE;QAClB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,qBAAqB;QAC3B,cAAc,EAAE,yCAAyC;QACzD,MAAM,EAAE,IAAI;KACb;IACD,eAAe,EAAE;QACf,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,mBAAmB;QACzB,cAAc,EAAE,sEAAsE;QACtF,MAAM,EAAE,IAAI;KACb;IACD,oBAAoB,EAAE;QACpB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,wBAAwB;QAC9B,cAAc,EAAE,+DAA+D;QAC/E,MAAM,EAAE,IAAI;KACb;IACD,WAAW,EAAE;QACX,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,cAAc;QACpB,cAAc,EAAE,gDAAgD;QAChE,MAAM,EAAE,IAAI;KACb;IACD,mBAAmB,EAAE;QACnB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,uBAAuB;QAC7B,cAAc,EAAE,mFAAmF;QACnG,MAAM,EAAE,KAAK;KACd;IACD,cAAc,EAAE;QACd,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,iBAAiB;QACvB,cAAc,EAAE,gFAAgF;QAChG,MAAM,EAAE,KAAK;KACd;IACD,uEAAuE;IACvE,+DAA+D;IAC/D,UAAU,EAAE;QACV,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,aAAa;QACnB,cAAc,EAAE,mEAAmE;QACnF,MAAM,EAAE,KAAK;KACd;IACD,kBAAkB,EAAE;QAClB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,qBAAqB;QAC3B,cAAc,EAAE,6EAA6E;QAC7F,MAAM,EAAE,IAAI;KACb;CACqD,CAAC;AAIzD,OAAO,EAAE,OAAO,EAAE,CAAC","sourcesContent":["/**\n * The single source of truth for HTTP-semantic errors.\n *\n * Eight repos carried this table as fourteen copy-pasted classes; the status,\n * machine code, and default message could drift per file. The catalog keeps all\n * three fields adjacent, so adding a status is one row, and a status can never\n * disagree with its code.\n *\n * `expose` marks whether the raw message may reach a client. Every 4xx is\n * trusted; every 5xx is not — a 5xx message is for operators, and\n * `toErrorResponse()` substitutes a generic one.\n */\ninterface HttpErrorDefinition {\n status: number;\n code: string;\n defaultMessage: string;\n expose: boolean;\n}\n\nconst CATALOG = {\n badRequest: {\n status: 400,\n code: 'BAD_REQUEST',\n defaultMessage: 'The request could not be understood or was missing required parameters.',\n expose: true,\n },\n unauthorized: {\n status: 401,\n code: 'UNAUTHORIZED',\n defaultMessage: 'Authentication is required and has failed or has not yet been provided.',\n expose: true,\n },\n forbidden: {\n status: 403,\n code: 'FORBIDDEN',\n defaultMessage: 'You do not have permission to perform this action.',\n expose: true,\n },\n notFound: {\n status: 404,\n code: 'NOT_FOUND',\n defaultMessage: 'The requested resource was not found.',\n expose: true,\n },\n methodNotAllowed: {\n status: 405,\n code: 'METHOD_NOT_ALLOWED',\n defaultMessage: 'The requested method is not allowed for this resource.',\n expose: true,\n },\n conflict: {\n // Distinct from `badRequest` so callers can tell \"invalid input\" from\n // \"that value is taken\" — the latter never succeeds without a change.\n status: 409,\n code: 'CONFLICT',\n defaultMessage: 'The request conflicts with the current state of the resource.',\n expose: true,\n },\n preconditionFailed: {\n status: 412,\n code: 'PRECONDITION_FAILED',\n defaultMessage: 'A precondition for this request failed.',\n expose: true,\n },\n payloadTooLarge: {\n status: 413,\n code: 'PAYLOAD_TOO_LARGE',\n defaultMessage: 'The request payload is larger than the server is willing to process.',\n expose: true,\n },\n unsupportedMediaType: {\n status: 415,\n code: 'UNSUPPORTED_MEDIA_TYPE',\n defaultMessage: 'The request payload format is not supported by this resource.',\n expose: true,\n },\n rateLimited: {\n status: 429,\n code: 'RATE_LIMITED',\n defaultMessage: 'Too many requests — slow down and retry later.',\n expose: true,\n },\n internalServerError: {\n status: 500,\n code: 'INTERNAL_SERVER_ERROR',\n defaultMessage: 'The server encountered an internal error and was unable to complete your request.',\n expose: false,\n },\n notImplemented: {\n status: 501,\n code: 'NOT_IMPLEMENTED',\n defaultMessage: 'The server does not support the functionality required to fulfil this request.',\n expose: false,\n },\n // Upstream dependency failures: 502 is the honest status here, and the\n // retryable marker (not the status) is what schedules a retry.\n badGateway: {\n status: 502,\n code: 'BAD_GATEWAY',\n defaultMessage: 'The server received an invalid response from an upstream service.',\n expose: false,\n },\n serviceUnavailable: {\n status: 503,\n code: 'SERVICE_UNAVAILABLE',\n defaultMessage: 'The server is currently unable to handle the request — retry after a delay.',\n expose: true,\n },\n} as const satisfies Record<string, HttpErrorDefinition>;\n\ntype HttpErrorType = keyof typeof CATALOG;\n\nexport { CATALOG };\nexport type { HttpErrorDefinition, HttpErrorType };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConflictError.js","sourceRoot":"","sources":["../src/ConflictError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,aAAc,SAAQ,gBAA4B;IACtD,YAAY,OAAgB;QAC1B,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC7B,CAAC;CACF;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"ConflictError.js","sourceRoot":"","sources":["../src/ConflictError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,aAAc,SAAQ,gBAA4B;IACtD,YAAY,OAAgB;QAC1B,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC7B,CAAC;CACF;AAED,OAAO,EAAE,aAAa,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 409 — well-formed but the resource state forbids it: a taken email, a\n * duplicate name, a stale precondition. Not retryable without a change.\n */\nclass ConflictError extends HttpServiceError<'conflict'> {\n constructor(message?: string) {\n super('conflict', message);\n }\n}\n\nexport { ConflictError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseError.js","sourceRoot":"","sources":["../src/DatabaseError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,aAAc,SAAQ,mBAAmB;IAC7C,YAAY,OAAgB,EAAE,YAAqB,KAAK,EAAE,OAA6B;QACrF,KAAK,CAAC,OAAO,IAAI,4EAA4E,EAAE,OAAO,CAAC,CAAC;QACxG,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"DatabaseError.js","sourceRoot":"","sources":["../src/DatabaseError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,aAAc,SAAQ,mBAAmB;IAC7C,YAAY,OAAgB,EAAE,YAAqB,KAAK,EAAE,OAA6B;QACrF,KAAK,CAAC,OAAO,IAAI,4EAA4E,EAAE,OAAO,CAAC,CAAC;QACxG,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,OAAO,EAAE,aAAa,EAAE,CAAC","sourcesContent":["import { InternalServerError } from './InternalServerError';\n\n/**\n * 500 for data-layer failures.\n *\n * Carries `retryable` because the difference between a transient D1 lock and a\n * constraint violation is invisible in the message — the caller's retry\n * decision (the DAO's) is encoded here as a flag instead of re-parsed at every\n * boundary.\n */\nclass DatabaseError extends InternalServerError {\n constructor(message?: string, retryable: boolean = false, options?: { cause?: unknown }) {\n super(message ?? 'The system encountered an unexpected problem while accessing the database.', options);\n this.retryable = retryable;\n this.type = 'DatabaseError';\n }\n}\n\nexport { DatabaseError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorResponse.js","sourceRoot":"","sources":["../src/ErrorResponse.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"ErrorResponse.js","sourceRoot":"","sources":["../src/ErrorResponse.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * The AWS-style error envelope: `{ \"Exception\": { \"Type\": \"...\", \"Message\": \"...\" } }`.\n *\n * Optional members tolerate foreign or truncated payloads during\n * deserialization; serializers always emit both fields. The envelope is the\n * family's established wire format — the kit's `toErrorResponse()` owns it so\n * per-app route layers stop hand-rolling it.\n */\ninterface ErrorResponse {\n Exception?: {\n Type?: string;\n Message?: string;\n };\n}\n\nexport type { ErrorResponse };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ForbiddenError.js","sourceRoot":"","sources":["../src/ForbiddenError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,cAAe,SAAQ,gBAA6B;IACxD,YAAY,OAAgB;QAC1B,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"ForbiddenError.js","sourceRoot":"","sources":["../src/ForbiddenError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,cAAe,SAAQ,gBAA6B;IACxD,YAAY,OAAgB;QAC1B,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,OAAO,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 403 — the caller is authenticated but the action is not theirs to take.\n */\nclass ForbiddenError extends HttpServiceError<'forbidden'> {\n constructor(message?: string) {\n super('forbidden', message);\n }\n}\n\nexport { ForbiddenError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpServiceError.js","sourceRoot":"","sources":["../src/HttpServiceError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;;;;GAKG;AACH,MAAe,gBAA8C,SAAQ,YAAY;IAC/E,YAAY,SAAgB,EAAE,OAAgB,EAAE,OAA6B;QAC3E,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QACtC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,IAAI,UAAU,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACrF,CAAC;CACF;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"HttpServiceError.js","sourceRoot":"","sources":["../src/HttpServiceError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;;;;GAKG;AACH,MAAe,gBAA8C,SAAQ,YAAY;IAC/E,YAAY,SAAgB,EAAE,OAAgB,EAAE,OAA6B;QAC3E,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QACtC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,IAAI,UAAU,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACrF,CAAC;CACF;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC","sourcesContent":["import { CATALOG } from './CATALOG';\nimport type { HttpErrorType } from './CATALOG';\nimport { ServiceError } from './ServiceError';\nimport type { ServiceErrorOptions } from './ServiceError';\n\n/**\n * A `ServiceError` with a fixed HTTP status and type from the catalog.\n *\n * Concrete subclasses add nothing but a name, so they are one-liners:\n * `class NotFoundError extends HttpServiceError<'notFound'> {}`.\n */\nabstract class HttpServiceError<TType extends HttpErrorType> extends ServiceError {\n constructor(errorType: TType, message?: string, options?: ServiceErrorOptions) {\n const definition = CATALOG[errorType];\n super(definition.status, errorType, message ?? definition.defaultMessage, options);\n }\n}\n\nexport { HttpServiceError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InternalServerError.js","sourceRoot":"","sources":["../src/InternalServerError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,mBAAoB,SAAQ,gBAAuC;IACvE,YAAY,OAAgB,EAAE,OAA6B;QACzD,KAAK,CAAC,qBAAqB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,0BAA0B,GAAG,IAAI,mBAAmB,EAAE,CAAC;AAE7D,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"InternalServerError.js","sourceRoot":"","sources":["../src/InternalServerError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,mBAAoB,SAAQ,gBAAuC;IACvE,YAAY,OAAgB,EAAE,OAA6B;QACzD,KAAK,CAAC,qBAAqB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,0BAA0B,GAAG,IAAI,mBAAmB,EAAE,CAAC;AAE7D,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 500 — the catch-all server fault.\n */\nclass InternalServerError extends HttpServiceError<'internalServerError'> {\n constructor(message?: string, options?: { cause?: unknown }) {\n super('internalServerError', message, options);\n }\n}\n\n/**\n * The instance returned to callers when the real cause must not be disclosed:\n * same stable type, generic message, regardless of what failed.\n */\nconst DefaultInternalServerError = new InternalServerError();\n\nexport { InternalServerError, DefaultInternalServerError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MethodNotAllowedError.js","sourceRoot":"","sources":["../src/MethodNotAllowedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,qBAAsB,SAAQ,gBAAoC;IACtE,YAAY,OAAgB;QAC1B,KAAK,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;CACF;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"MethodNotAllowedError.js","sourceRoot":"","sources":["../src/MethodNotAllowedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,qBAAsB,SAAQ,gBAAoC;IACtE,YAAY,OAAgB;QAC1B,KAAK,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;CACF;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 405 — the method exists but not on this path.\n */\nclass MethodNotAllowedError extends HttpServiceError<'methodNotAllowed'> {\n constructor(message?: string) {\n super('methodNotAllowed', message);\n }\n}\n\nexport { MethodNotAllowedError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotFoundError.js","sourceRoot":"","sources":["../src/NotFoundError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,aAAc,SAAQ,gBAA4B;IACtD,YAAY,OAAgB;QAC1B,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC7B,CAAC;CACF;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"NotFoundError.js","sourceRoot":"","sources":["../src/NotFoundError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,aAAc,SAAQ,gBAA4B;IACtD,YAAY,OAAgB;QAC1B,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC7B,CAAC;CACF;AAED,OAAO,EAAE,aAAa,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 404 — no such resource.\n */\nclass NotFoundError extends HttpServiceError<'notFound'> {\n constructor(message?: string) {\n super('notFound', message);\n }\n}\n\nexport { NotFoundError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotImplementedError.js","sourceRoot":"","sources":["../src/NotImplementedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,mBAAoB,SAAQ,gBAAkC;IAClE,YAAY,OAAgB;QAC1B,KAAK,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;CACF;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"NotImplementedError.js","sourceRoot":"","sources":["../src/NotImplementedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,mBAAoB,SAAQ,gBAAkC;IAClE,YAAY,OAAgB;QAC1B,KAAK,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;CACF;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 501 — the functionality exists in the protocol but not on this deployment.\n */\nclass NotImplementedError extends HttpServiceError<'notImplemented'> {\n constructor(message?: string) {\n super('notImplemented', message);\n }\n}\n\nexport { NotImplementedError };\n"]}
|
package/dist/OutcomeError.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OutcomeError.js","sourceRoot":"","sources":["../src/OutcomeError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;;;;;;;GAQG;AACH,MAAM,YAAa,SAAQ,YAAY;IACrC,YAAY,OAAe,EAAE,OAAqD;QAChF,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,cAAe,SAAQ,YAAY;IACvC,YAAY,OAAe,EAAE,MAAe;QAC1C,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/F,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,CAAC;IACH,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,iBAAkB,SAAQ,YAAY;IAC1C,YAAY,OAAe,EAAE,MAAe;QAC1C,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAChG,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,CAAC;IACH,CAAC;CACF;AAED,MAAM,yBAA0B,SAAQ,cAAc;CAAG;AACzD,MAAM,4BAA6B,SAAQ,iBAAiB;CAAG;AAC/D,MAAM,yBAA0B,SAAQ,cAAc;CAAG;AACzD,MAAM,4BAA6B,SAAQ,iBAAiB;CAAG;AAE/D,OAAO,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,yBAAyB,EACzB,YAAY,EACZ,4BAA4B,EAC5B,yBAAyB,EACzB,cAAc,GACf,CAAC"}
|
|
1
|
+
{"version":3,"file":"OutcomeError.js","sourceRoot":"","sources":["../src/OutcomeError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;;;;;;;GAQG;AACH,MAAM,YAAa,SAAQ,YAAY;IACrC,YAAY,OAAe,EAAE,OAAqD;QAChF,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,cAAe,SAAQ,YAAY;IACvC,YAAY,OAAe,EAAE,MAAe;QAC1C,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/F,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,CAAC;IACH,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,iBAAkB,SAAQ,YAAY;IAC1C,YAAY,OAAe,EAAE,MAAe;QAC1C,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAChG,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,CAAC;IACH,CAAC;CACF;AAED,MAAM,yBAA0B,SAAQ,cAAc;CAAG;AACzD,MAAM,4BAA6B,SAAQ,iBAAiB;CAAG;AAC/D,MAAM,yBAA0B,SAAQ,cAAc;CAAG;AACzD,MAAM,4BAA6B,SAAQ,iBAAiB;CAAG;AAE/D,OAAO,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,yBAAyB,EACzB,YAAY,EACZ,4BAA4B,EAC5B,yBAAyB,EACzB,cAAc,GACf,CAAC","sourcesContent":["import { ServiceError } from './ServiceError';\nimport type { ServiceErrorOptions } from './ServiceError';\n\n/**\n * An error whose retryability is decided by the thrower, not deduced.\n *\n * Durable-DAV's `D1ErrorClassifier` can classify a raw D1 message, but a\n * provider-level failure (OAuth2 grant revoked, upstream API rejecting a\n * payload) carries no such signal — only the code that made the call knows.\n * This taxonomy lets that code say so explicitly, and the status defaults\n * follow the retry flag rather than a name-lookup table that could disagree.\n */\nclass OutcomeError extends ServiceError {\n constructor(message: string, options: ServiceErrorOptions & { retryable: boolean }) {\n super(options.retryable ? 502 : 400, new.target.name, message, options);\n }\n}\n\n/**\n * Transient upstream failure: a later attempt may succeed (throttling, 5xx\n * from the provider, token refresh race). Status 502 by default.\n */\nclass RetryableError extends OutcomeError {\n constructor(message: string, status?: number) {\n super(message, { retryable: true, ...(status === undefined ? {} : { expose: status < 500 }) });\n if (status !== undefined) {\n this.status = status;\n }\n }\n}\n\n/**\n * Permanent failure: retrying repeats the failure forever. A revoked grant\n * retried every ten minutes told the caller the request was a server fault;\n * this class exists so that never reads as retryable again. Status 400.\n */\nclass NonRetryableError extends OutcomeError {\n constructor(message: string, status?: number) {\n super(message, { retryable: false, ...(status === undefined ? {} : { expose: status < 500 }) });\n if (status !== undefined) {\n this.status = status;\n }\n }\n}\n\nclass ProviderApiRetryableError extends RetryableError {}\nclass ProviderApiNonRetryableError extends NonRetryableError {}\nclass OAuth2TokenRetryableError extends RetryableError {}\nclass OAuth2TokenNonRetryableError extends NonRetryableError {}\n\nexport {\n NonRetryableError,\n OAuth2TokenNonRetryableError,\n OAuth2TokenRetryableError,\n OutcomeError,\n ProviderApiNonRetryableError,\n ProviderApiRetryableError,\n RetryableError,\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PayloadTooLargeError.js","sourceRoot":"","sources":["../src/PayloadTooLargeError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,oBAAqB,SAAQ,gBAAmC;IACpE,YAAY,OAAgB;QAC1B,KAAK,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;CACF;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"PayloadTooLargeError.js","sourceRoot":"","sources":["../src/PayloadTooLargeError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,oBAAqB,SAAQ,gBAAmC;IACpE,YAAY,OAAgB;QAC1B,KAAK,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;CACF;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 413 — the payload exceeds the server's limits (request body, file, batch).\n */\nclass PayloadTooLargeError extends HttpServiceError<'payloadTooLarge'> {\n constructor(message?: string) {\n super('payloadTooLarge', message);\n }\n}\n\nexport { PayloadTooLargeError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreconditionFailedError.js","sourceRoot":"","sources":["../src/PreconditionFailedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,uBAAwB,SAAQ,gBAAsC;IAC1E,YAAY,OAAgB;QAC1B,KAAK,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;CACF;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"PreconditionFailedError.js","sourceRoot":"","sources":["../src/PreconditionFailedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,uBAAwB,SAAQ,gBAAsC;IAC1E,YAAY,OAAgB;QAC1B,KAAK,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;CACF;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 412 — a precondition the caller supplied (e.g. `If-Match`, expected state)\n * did not hold. Retrying unmodified fails by definition.\n */\nclass PreconditionFailedError extends HttpServiceError<'preconditionFailed'> {\n constructor(message?: string) {\n super('preconditionFailed', message);\n }\n}\n\nexport { PreconditionFailedError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimitedError.js","sourceRoot":"","sources":["../src/RateLimitedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,gBAAiB,SAAQ,gBAA+B;IAC5D,YAAY,OAAgB;QAC1B,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;CACF;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"RateLimitedError.js","sourceRoot":"","sources":["../src/RateLimitedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,gBAAiB,SAAQ,gBAA+B;IAC5D,YAAY,OAAgB;QAC1B,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;CACF;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 429 — the caller exceeded its rate budget. Retrying is not just futile but\n * punished; honor `retryAfter`-style backoff at the caller.\n */\nclass RateLimitedError extends HttpServiceError<'rateLimited'> {\n constructor(message?: string) {\n super('rateLimited', message);\n }\n}\n\nexport { RateLimitedError };\n"]}
|
package/dist/ServiceError.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceError.js","sourceRoot":"","sources":["../src/ServiceError.ts"],"names":[],"mappings":"AAgBA,MAAM,uBAAuB,GAAG,mFAAmF,CAAC;AAEpH;;;;;;;;;;;GAWG;AACH,MAAe,YAAa,SAAQ,KAAK;IACvC,4EAA4E;IACrE,MAAM,CAAS;IAEtB,iFAAiF;IAC1E,IAAI,CAAS;IAEpB,iEAAiE;IAC1D,SAAS,CAAU;IAE1B,8EAA8E;IACvE,MAAM,CAAU;IAEvB,YAAY,MAAc,EAAE,IAAY,EAAE,OAAe,EAAE,OAA6B;QACtF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,2EAA2E;QAC3E,yEAAyE;QACzE,oCAAoC;QACpC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,KAAK,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,MAAM,GAAG,GAAG,CAAC;QAC9C,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC7B,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,eAAe;QACpB,MAAM,OAAO,GAAW,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;QAC7E,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE;gBACJ,SAAS,EAAE;oBACT,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,OAAO,EAAE,OAAO;iBACjB;aACF;SACF,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,IAAI,CAAC,KAAc;QAC/B,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,IAAI,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,IAAI,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,oBAAqB,SAAQ,YAAY;IAC7C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;CACF;AAED,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"ServiceError.js","sourceRoot":"","sources":["../src/ServiceError.ts"],"names":[],"mappings":"AAgBA,MAAM,uBAAuB,GAAG,mFAAmF,CAAC;AAEpH;;;;;;;;;;;GAWG;AACH,MAAe,YAAa,SAAQ,KAAK;IACvC,4EAA4E;IACrE,MAAM,CAAS;IAEtB,iFAAiF;IAC1E,IAAI,CAAS;IAEpB,iEAAiE;IAC1D,SAAS,CAAU;IAE1B,8EAA8E;IACvE,MAAM,CAAU;IAEvB,YAAY,MAAc,EAAE,IAAY,EAAE,OAAe,EAAE,OAA6B;QACtF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,2EAA2E;QAC3E,yEAAyE;QACzE,oCAAoC;QACpC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,KAAK,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,MAAM,GAAG,GAAG,CAAC;QAC9C,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC7B,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,eAAe;QACpB,MAAM,OAAO,GAAW,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;QAC7E,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE;gBACJ,SAAS,EAAE;oBACT,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,OAAO,EAAE,OAAO;iBACjB;aACF;SACF,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,IAAI,CAAC,KAAc;QAC/B,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,IAAI,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,IAAI,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,oBAAqB,SAAQ,YAAY;IAC7C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;CACF;AAED,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,CAAC","sourcesContent":["import type { ErrorResponse } from './ErrorResponse';\n\ninterface ServiceErrorOptions {\n /** Marks a transient failure: a caller retrying is meaningful. */\n retryable?: boolean;\n /** Whether the raw message may reach a client. Defaults to `status < 500`. */\n expose?: boolean;\n /** Underlying cause, preserved for operator-facing logs. */\n cause?: unknown;\n}\n\ninterface ErrorHttpPayload {\n status: number;\n body: ErrorResponse;\n}\n\nconst INTERNAL_SERVER_MESSAGE = 'The server encountered an internal error and was unable to complete your request.';\n\n/**\n * Root of the error taxonomy.\n *\n * Every boundary in the family (route handlers, middleware, background tasks)\n * branches on `instanceof ServiceError`, so every concrete error must genuinely\n * extend it — an `implements` leaves the prototype chain broken and silently\n * masks typed errors as generic 500s.\n *\n * Status/type/retryable/expose are public fields, not methods: the values are\n * fixed at construction, and callers in all nine repos read them far more often\n * than they were ever written.\n */\nabstract class ServiceError extends Error {\n /** The HTTP status. Defaults from the catalog; a subclass may refine it. */\n public status: number;\n\n /** Overridable by subclasses whose identity differs from the HTTP class name. */\n public type: string;\n\n /** False by default: retrying is the exception, not the rule. */\n public retryable: boolean;\n\n /** Whether the raw message may reach a client. Defaults to `status < 500`. */\n public expose: boolean;\n\n constructor(status: number, type: string, message: string, options?: ServiceErrorOptions) {\n super(message);\n // `new.target.name` rather than the passed type: a subclass reports itself\n // even if its author forgot to name it, so log lines and client payloads\n // never disagree about what failed.\n this.name = new.target.name;\n this.status = status;\n this.type = type;\n this.retryable = options?.retryable ?? false;\n this.expose = options?.expose ?? status < 500;\n if (options?.cause !== undefined) {\n this.cause = options.cause;\n }\n }\n\n /**\n * The wire form: status plus the family's `ErrorResponse` envelope.\n *\n * A non-exposing error (5xx) has its message substituted — `message` is for\n * operators, and pushing it to clients leaks internals. The substitution\n * lives here, once, rather than in nine boundary mappers.\n */\n public toErrorResponse(): ErrorHttpPayload {\n const message: string = this.expose ? this.message : INTERNAL_SERVER_MESSAGE;\n return {\n status: this.status,\n body: {\n Exception: {\n Type: this.type,\n Message: message,\n },\n },\n };\n }\n\n /**\n * Normalize an unknown catch-block value into the taxonomy.\n *\n * A `ServiceError` passes through untouched (re-wrapping would bury its\n * context); anything else becomes a non-retryable 500 carrying the original\n * message and cause. Boundary code should call this before mapping an error\n * to a response, so `error instanceof ServiceError` is guaranteed downstream.\n */\n public static from(error: unknown): ServiceError {\n if (error instanceof ServiceError) {\n return error;\n }\n if (error instanceof Error) {\n return new InternalServiceError(error.message, { cause: error });\n }\n return new InternalServiceError(String(error), { cause: error });\n }\n}\n\n/**\n * Private throwable used by `ServiceError.from` for pass-through wrapping.\n * Not exported: reach `InternalServerError` for the public 500.\n */\nclass InternalServiceError extends ServiceError {\n constructor(message: string, options?: ServiceErrorOptions) {\n super(500, 'InternalError', message, options);\n }\n}\n\nexport { ServiceError, InternalServiceError };\nexport type { ServiceErrorOptions, ErrorHttpPayload };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceUnavailableError.js","sourceRoot":"","sources":["../src/ServiceUnavailableError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,uBAAwB,SAAQ,gBAAsC;IAC1E,YAAY,OAAgB;QAC1B,KAAK,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;CACF;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"ServiceUnavailableError.js","sourceRoot":"","sources":["../src/ServiceUnavailableError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,uBAAwB,SAAQ,gBAAsC;IAC1E,YAAY,OAAgB;QAC1B,KAAK,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;CACF;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 503 — unavailable now, healthy later. The natural status for retryable\n * infrastructure failures (a locked D1, an overloaded upstream).\n */\nclass ServiceUnavailableError extends HttpServiceError<'serviceUnavailable'> {\n constructor(message?: string) {\n super('serviceUnavailable', message);\n }\n}\n\nexport { ServiceUnavailableError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnauthorizedError.js","sourceRoot":"","sources":["../src/UnauthorizedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,iBAAkB,SAAQ,gBAAgC;IAC9D,YAAY,OAAgB;QAC1B,KAAK,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;CACF;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"UnauthorizedError.js","sourceRoot":"","sources":["../src/UnauthorizedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,iBAAkB,SAAQ,gBAAgC;IAC9D,YAAY,OAAgB;QAC1B,KAAK,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;CACF;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 401 — credentials missing, expired, or rejected. Distinct from `Forbidden`:\n * re-authenticating may help; `Forbidden` it will not.\n */\nclass UnauthorizedError extends HttpServiceError<'unauthorized'> {\n constructor(message?: string) {\n super('unauthorized', message);\n }\n}\n\nexport { UnauthorizedError };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnsupportedMediaTypeError.js","sourceRoot":"","sources":["../src/UnsupportedMediaTypeError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,yBAA0B,SAAQ,gBAAwC;IAC9E,YAAY,OAAgB;QAC1B,KAAK,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;CACF;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"UnsupportedMediaTypeError.js","sourceRoot":"","sources":["../src/UnsupportedMediaTypeError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,yBAA0B,SAAQ,gBAAwC;IAC9E,YAAY,OAAgB;QAC1B,KAAK,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;CACF;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAC","sourcesContent":["import { HttpServiceError } from './HttpServiceError';\n\n/**\n * 415 — the body's content type is not one the endpoint can parse.\n */\nclass UnsupportedMediaTypeError extends HttpServiceError<'unsupportedMediaType'> {\n constructor(message?: string) {\n super('unsupportedMediaType', message);\n }\n}\n\nexport { UnsupportedMediaTypeError };\n"]}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,yBAAyB,EACzB,YAAY,EACZ,4BAA4B,EAC5B,yBAAyB,EACzB,cAAc,GACf,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,yBAAyB,EACzB,YAAY,EACZ,4BAA4B,EAC5B,yBAAyB,EACzB,cAAc,GACf,MAAM,gBAAgB,CAAC","sourcesContent":["export { CATALOG } from './CATALOG';\nexport type { HttpErrorDefinition, HttpErrorType } from './CATALOG';\nexport { ServiceError } from './ServiceError';\nexport type { ServiceErrorOptions, ErrorHttpPayload } from './ServiceError';\nexport { HttpServiceError } from './HttpServiceError';\nexport { BadRequestError } from './BadRequestError';\nexport { UnauthorizedError } from './UnauthorizedError';\nexport { ForbiddenError } from './ForbiddenError';\nexport { NotFoundError } from './NotFoundError';\nexport { MethodNotAllowedError } from './MethodNotAllowedError';\nexport { ConflictError } from './ConflictError';\nexport { PreconditionFailedError } from './PreconditionFailedError';\nexport { PayloadTooLargeError } from './PayloadTooLargeError';\nexport { UnsupportedMediaTypeError } from './UnsupportedMediaTypeError';\nexport { RateLimitedError } from './RateLimitedError';\nexport { InternalServerError, DefaultInternalServerError } from './InternalServerError';\nexport { NotImplementedError } from './NotImplementedError';\nexport { BadGatewayError } from './BadGatewayError';\nexport { ServiceUnavailableError } from './ServiceUnavailableError';\nexport { DatabaseError } from './DatabaseError';\nexport {\n NonRetryableError,\n OAuth2TokenNonRetryableError,\n OAuth2TokenRetryableError,\n OutcomeError,\n ProviderApiNonRetryableError,\n ProviderApiRetryableError,\n RetryableError,\n} from './OutcomeError';\nexport type { ErrorResponse } from './ErrorResponse';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rexezuge/errors",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"typescript": "6.0.3",
|
|
30
30
|
"vitest": "4.1.11"
|
|
31
31
|
},
|
|
32
|
+
"description": "Catalog-driven HTTP/service error taxonomy with retry markers and wire envelopes for the Rexezuge-CloudflareWorkers family.",
|
|
32
33
|
"scripts": {
|
|
33
34
|
"build": "tsc -p tsconfig.json",
|
|
34
35
|
"typecheck": "tsc -p tsconfig.test.json --noEmit",
|