@lunora/errors 1.0.0-alpha.1 → 1.0.0-alpha.11
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/LICENSE.md +6 -0
- package/dist/index.d.mts +584 -81
- package/dist/index.d.ts +584 -81
- package/dist/index.mjs +1 -5
- package/dist/packem_shared/CLOUDFLARE_PLATFORM_ERRORS-D98lVLGc.mjs +14 -0
- package/dist/packem_shared/LunoraError-MUTWZDbD.mjs +1 -0
- package/dist/packem_shared/invariant-CnwAr0oB.mjs +1 -0
- package/dist/packem_shared/isLunoraError-Dvew97xn.mjs +1 -0
- package/dist/packem_shared/toErrorBody-l1H3-utl.mjs +1 -0
- package/package.json +1 -1
- package/dist/packem_shared/ERROR_CATALOG-D3knuUQT.mjs +0 -207
- package/dist/packem_shared/LunoraError-bpS_TPIe.mjs +0 -38
- package/dist/packem_shared/invariant-DLXTsHpj.mjs +0 -12
- package/dist/packem_shared/isLunoraError-BvsoKcWE.mjs +0 -9
- package/dist/packem_shared/toErrorBody-DihI5p4Q.mjs +0 -26
package/dist/index.d.mts
CHANGED
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The central Lunora error catalog — the single source of truth mapping a
|
|
3
|
-
* machine-readable `code` to its transport `status`, a short human `title`, and
|
|
4
|
-
* (where useful) an actionable Markdown `hint` plus a `docsUrl`.
|
|
5
|
-
*
|
|
6
|
-
* This table is consumed everywhere an error is surfaced: the runtime/DO wire
|
|
7
|
-
* mappers (status), the client SDK (code discrimination), the CLI renderer and
|
|
8
|
-
* the Vite overlay (hint), and the Studio UI (title + hint + docs link). It also
|
|
9
|
-
* absorbs the former `@lunora/codegen` "solutions" table (see {@link MESSAGE_SOLUTIONS})
|
|
10
|
-
* so codegen build-time errors — which are thrown as plain messages into
|
|
11
|
-
* generated code and lose their class identity before a consumer sees them —
|
|
12
|
-
* keep their message-matched hints.
|
|
13
|
-
*/
|
|
14
1
|
/** Markdown hint: a single string or an array of lines. Shape matches `@visulima/error`'s `hint`. */
|
|
15
|
-
type ErrorHint = string | string
|
|
2
|
+
type ErrorHint = string | ReadonlyArray<string>;
|
|
16
3
|
/** A catalog entry: the fixed metadata for one error `code`. */
|
|
17
4
|
interface ErrorCatalogEntry {
|
|
18
5
|
/** Optional URL to deeper docs for this error. */
|
|
@@ -20,11 +7,11 @@ interface ErrorCatalogEntry {
|
|
|
20
7
|
/** Optional actionable fix, authored as Markdown (rendered by CLI/overlay/Studio). */
|
|
21
8
|
hint?: ErrorHint;
|
|
22
9
|
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
10
|
+
* When `true`, this code's `message` must NOT cross the wire — an internal
|
|
11
|
+
* failure or unhandled invariant may carry SQL fragments, file paths, or
|
|
12
|
+
* internal identifiers. The transport mappers emit a generic message for
|
|
13
|
+
* these (and log the real one server-side). See {@link isInternalCode}.
|
|
14
|
+
*/
|
|
28
15
|
internal?: boolean;
|
|
29
16
|
/** HTTP/RPC status this code maps to on the wire. */
|
|
30
17
|
status: number;
|
|
@@ -32,10 +19,10 @@ interface ErrorCatalogEntry {
|
|
|
32
19
|
title: string;
|
|
33
20
|
}
|
|
34
21
|
/**
|
|
35
|
-
* Every well-known Lunora error code. Domain packages may throw additional
|
|
36
|
-
* codes (passing an explicit `status`); those are added here as their package is
|
|
37
|
-
* migrated. The keys of this object form the {@link LunoraErrorCode} union.
|
|
38
|
-
*/
|
|
22
|
+
* Every well-known Lunora error code. Domain packages may throw additional
|
|
23
|
+
* codes (passing an explicit `status`); those are added here as their package is
|
|
24
|
+
* migrated. The keys of this object form the {@link LunoraErrorCode} union.
|
|
25
|
+
*/
|
|
39
26
|
declare const ERROR_CATALOG: {
|
|
40
27
|
readonly BAD_REQUEST: {
|
|
41
28
|
readonly status: 400;
|
|
@@ -59,9 +46,9 @@ declare const ERROR_CATALOG: {
|
|
|
59
46
|
readonly title: "Conflict";
|
|
60
47
|
};
|
|
61
48
|
readonly NOT_UNIQUE: {
|
|
62
|
-
readonly hint: readonly ["
|
|
49
|
+
readonly hint: readonly ["`.unique()` matched more than one document — it expects the query to identify at most one row.", "", "- If several matches are legitimate, use `.first()` (take one) or `.collect()` (take all) instead.", "- Otherwise tighten the query (e.g. filter on a unique/indexed field) so it can only match one row."];
|
|
63
50
|
readonly status: 400;
|
|
64
|
-
readonly title: "
|
|
51
|
+
readonly title: "Query matched more than one document";
|
|
65
52
|
};
|
|
66
53
|
readonly VALIDATION_ERROR: {
|
|
67
54
|
readonly status: 400;
|
|
@@ -78,7 +65,8 @@ declare const ERROR_CATALOG: {
|
|
|
78
65
|
readonly NOT_IMPLEMENTED: {
|
|
79
66
|
readonly status: 501;
|
|
80
67
|
readonly title: "Not implemented";
|
|
81
|
-
};
|
|
68
|
+
};
|
|
69
|
+
/** RPC/REST dispatch codes emitted by the runtime + Durable Object router. */
|
|
82
70
|
readonly FUNCTION_NOT_FOUND: {
|
|
83
71
|
readonly status: 404;
|
|
84
72
|
readonly title: "Function not found";
|
|
@@ -90,7 +78,8 @@ declare const ERROR_CATALOG: {
|
|
|
90
78
|
readonly PAYLOAD_TOO_LARGE: {
|
|
91
79
|
readonly status: 413;
|
|
92
80
|
readonly title: "Payload too large";
|
|
93
|
-
};
|
|
81
|
+
};
|
|
82
|
+
/** Free-form internal failure — redacted to a generic message on the wire. */
|
|
94
83
|
readonly INTERNAL: {
|
|
95
84
|
readonly internal: true;
|
|
96
85
|
readonly status: 500;
|
|
@@ -125,6 +114,28 @@ declare const ERROR_CATALOG: {
|
|
|
125
114
|
readonly status: 403;
|
|
126
115
|
readonly title: "RLS policy required";
|
|
127
116
|
};
|
|
117
|
+
readonly RUN_DEPTH_EXCEEDED: {
|
|
118
|
+
readonly internal: true;
|
|
119
|
+
readonly status: 500;
|
|
120
|
+
readonly title: "Run depth exceeded";
|
|
121
|
+
};
|
|
122
|
+
readonly TRANSACTION_LIMIT_EXCEEDED: {
|
|
123
|
+
readonly hint: readonly ["A single mutation may only read and write a bounded amount before it is stopped.", "", "Narrow the read with an index (`.withIndex(...)`) instead of scanning the table, or split the write across several mutations — for a large backfill use `defineMigration` + `lunora migrate up`, which batches and checkpoints for you.", "", "The ceilings are deliberately conservative — they exist to stop one request taking down the whole shard. A deployment that genuinely needs bigger transactions can raise them by overriding the `transactionLimits()` seam on its generated shard class."];
|
|
124
|
+
readonly status: 413;
|
|
125
|
+
readonly title: "Transaction limit exceeded";
|
|
126
|
+
};
|
|
127
|
+
readonly MIGRATION_NOT_FOUND: {
|
|
128
|
+
readonly status: 404;
|
|
129
|
+
readonly title: "Data migration not found";
|
|
130
|
+
};
|
|
131
|
+
readonly UNKNOWN_TABLE: {
|
|
132
|
+
readonly status: 404;
|
|
133
|
+
readonly title: "Unknown table";
|
|
134
|
+
};
|
|
135
|
+
readonly GLOBAL_TABLE_NOT_EDITABLE: {
|
|
136
|
+
readonly status: 400;
|
|
137
|
+
readonly title: "Global table is not editable";
|
|
138
|
+
};
|
|
128
139
|
readonly SHARD_ERROR: {
|
|
129
140
|
readonly status: 503;
|
|
130
141
|
readonly title: "Shard error";
|
|
@@ -136,29 +147,55 @@ declare const ERROR_CATALOG: {
|
|
|
136
147
|
readonly OFFLINE_IDENTITY_CHANGED: {
|
|
137
148
|
readonly status: 409;
|
|
138
149
|
readonly title: "Offline identity changed";
|
|
139
|
-
};
|
|
150
|
+
};
|
|
151
|
+
/** Package-specific codes. Build-time-only — never cross the RPC wire, so deliberately not `internal`. */
|
|
140
152
|
readonly CODEGEN_DIAGNOSTIC: {
|
|
141
153
|
readonly status: 500;
|
|
142
154
|
readonly title: "Codegen diagnostic";
|
|
143
155
|
};
|
|
156
|
+
/** Build-time-only — never crosses the RPC wire, so deliberately not `internal`. */
|
|
144
157
|
readonly SCHEMA_SNAPSHOT_PARSE: {
|
|
145
158
|
readonly status: 500;
|
|
146
159
|
readonly title: "Schema snapshot parse error";
|
|
147
160
|
};
|
|
161
|
+
/** Runtime-reachable (env.ts): message enumerates failing env key names — redact on the wire. */
|
|
148
162
|
readonly ENV_INVALID: {
|
|
163
|
+
readonly internal: true;
|
|
149
164
|
readonly status: 500;
|
|
150
165
|
readonly title: "Invalid environment";
|
|
151
166
|
};
|
|
167
|
+
/** Runtime-reachable (auth/middleware.ts): message carries auth-wiring guidance — redact on the wire. */
|
|
152
168
|
readonly AUTH_HEADERS_MISSING: {
|
|
169
|
+
readonly internal: true;
|
|
153
170
|
readonly status: 500;
|
|
154
171
|
readonly title: "Auth headers missing";
|
|
155
172
|
};
|
|
156
173
|
/**
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
174
|
+
* Signup rejected by `@lunora/auth`'s email-domain gate — a disposable/throwaway
|
|
175
|
+
* provider (or a caller deny-list hit). Client-safe: the message names only the
|
|
176
|
+
* offending domain class, never a secret, so it is echoed rather than redacted.
|
|
177
|
+
*/
|
|
178
|
+
readonly EMAIL_DOMAIN_BLOCKED: {
|
|
179
|
+
readonly hint: readonly ["This address's domain is on the disposable/throwaway blocklist (or your configured deny-list).", "", "Sign up with a permanent mailbox. To tune the policy, pass `blockDisposable` / `allowDomains` / `denyDomains` to `emailGate(...)` (`@lunora/auth/email-guard`)."];
|
|
180
|
+
readonly status: 400;
|
|
181
|
+
readonly title: "Email domain not allowed";
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Opt-in MX verification (`@lunora/auth/email-guard`, `mx: true`) found no mail
|
|
185
|
+
* exchanger for the address's domain, so mail to it would never deliver.
|
|
186
|
+
* Client-safe: names only the domain, no secret.
|
|
187
|
+
*/
|
|
188
|
+
readonly EMAIL_UNDELIVERABLE: {
|
|
189
|
+
readonly hint: readonly ["The address's domain publishes no MX (or fallback A/AAAA) records, so it can't receive mail.", "", "Check for a typo in the domain. MX verification is opt-in (`mx: true`) and needs DNS — leave it off on the edge path if DNS is unavailable."];
|
|
190
|
+
readonly status: 400;
|
|
191
|
+
readonly title: "Email domain cannot receive mail";
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Upstream Cloudflare API failures surfaced from an action. The message
|
|
195
|
+
* carries the upstream response body (Cloudflare's own error text — trusted
|
|
196
|
+
* infra, not user input), so it is echoed rather than redacted. `status`
|
|
197
|
+
* here is a fallback; each throw passes the actual upstream HTTP status.
|
|
198
|
+
*/
|
|
162
199
|
readonly ANALYTICS_SQL_ERROR: {
|
|
163
200
|
readonly status: 502;
|
|
164
201
|
readonly title: "Analytics Engine SQL API error";
|
|
@@ -171,25 +208,419 @@ declare const ERROR_CATALOG: {
|
|
|
171
208
|
readonly status: 502;
|
|
172
209
|
readonly title: "Cloudflare Workflows REST API error";
|
|
173
210
|
};
|
|
211
|
+
/**
|
|
212
|
+
* Admin-gated `/_lunora/admin/*` and `__lunora_admin__:*` codes. Registered
|
|
213
|
+
* here (plan 230, ERRORS-01) after an audit found them minted with `code:`
|
|
214
|
+
* but never added to the catalog — `isInternalCode` fails OPEN for an
|
|
215
|
+
* unregistered code, so each was already echoing its message unredacted.
|
|
216
|
+
* Below is that audit's verdict per code, not a blanket allow: most of these
|
|
217
|
+
* are deliberately actionable ("you forgot to configure X") and stay
|
|
218
|
+
* client-safe; the ones that can carry backend detail are flagged
|
|
219
|
+
* `internal: true` individually, with the reason noted alongside.
|
|
220
|
+
*/
|
|
221
|
+
readonly ADMIN_FORBIDDEN: {
|
|
222
|
+
readonly status: 403;
|
|
223
|
+
readonly title: "Admin access forbidden";
|
|
224
|
+
};
|
|
225
|
+
readonly ADMIN_TOKEN_NOT_CONFIGURED: {
|
|
226
|
+
readonly status: 400;
|
|
227
|
+
readonly title: "Admin token not configured";
|
|
228
|
+
};
|
|
229
|
+
readonly AUTH_NOT_CONFIGURED: {
|
|
230
|
+
readonly status: 400;
|
|
231
|
+
readonly title: "Auth admin not configured";
|
|
232
|
+
};
|
|
233
|
+
readonly AUTH_OP_NOT_SUPPORTED: {
|
|
234
|
+
readonly status: 400;
|
|
235
|
+
readonly title: "Auth admin operation not supported";
|
|
236
|
+
};
|
|
237
|
+
readonly BACKUP_NOT_CONFIGURED: {
|
|
238
|
+
readonly status: 500;
|
|
239
|
+
readonly title: "Scheduled backup not configured";
|
|
240
|
+
};
|
|
241
|
+
readonly CRON_JOBS_NOT_CONFIGURED: {
|
|
242
|
+
readonly status: 400;
|
|
243
|
+
readonly title: "Cron jobs not configured";
|
|
244
|
+
};
|
|
245
|
+
readonly CRON_JOB_NOT_FOUND: {
|
|
246
|
+
readonly status: 404;
|
|
247
|
+
readonly title: "Cron job not found";
|
|
248
|
+
};
|
|
249
|
+
readonly EXPORT_TAP_NOT_CONFIGURED: {
|
|
250
|
+
readonly status: 400;
|
|
251
|
+
readonly title: "Export tap not configured";
|
|
252
|
+
};
|
|
253
|
+
readonly FUNCTIONS_NOT_CONFIGURED: {
|
|
254
|
+
readonly status: 400;
|
|
255
|
+
readonly title: "Functions registry not configured";
|
|
256
|
+
};
|
|
257
|
+
readonly GLOBALS_NOT_CONFIGURED: {
|
|
258
|
+
readonly status: 400;
|
|
259
|
+
readonly title: "Global-table introspector not configured";
|
|
260
|
+
};
|
|
261
|
+
readonly KV_NOT_CONFIGURED: {
|
|
262
|
+
readonly status: 400;
|
|
263
|
+
readonly title: "KV introspector not configured";
|
|
264
|
+
};
|
|
265
|
+
readonly MIGRATION_ID_REQUIRED: {
|
|
266
|
+
readonly status: 400;
|
|
267
|
+
readonly title: "Migration id required";
|
|
268
|
+
};
|
|
269
|
+
readonly PITR_UNAVAILABLE: {
|
|
270
|
+
readonly status: 409;
|
|
271
|
+
readonly title: "Point-in-time recovery unavailable";
|
|
272
|
+
};
|
|
273
|
+
readonly SCHEDULER_NOT_CONFIGURED: {
|
|
274
|
+
readonly status: 400;
|
|
275
|
+
readonly title: "Scheduler not configured";
|
|
276
|
+
};
|
|
277
|
+
readonly STORAGE_DELETE_NOT_CONFIGURED: {
|
|
278
|
+
readonly status: 400;
|
|
279
|
+
readonly title: "Storage delete not configured";
|
|
280
|
+
};
|
|
281
|
+
readonly STORAGE_NOT_CONFIGURED: {
|
|
282
|
+
readonly status: 400;
|
|
283
|
+
readonly title: "Storage not configured";
|
|
284
|
+
};
|
|
285
|
+
readonly STORAGE_UPLOAD_NOT_CONFIGURED: {
|
|
286
|
+
readonly status: 400;
|
|
287
|
+
readonly title: "Storage upload not configured";
|
|
288
|
+
};
|
|
289
|
+
readonly STORAGE_URL_NOT_CONFIGURED: {
|
|
290
|
+
readonly status: 400;
|
|
291
|
+
readonly title: "Storage signed URL not configured";
|
|
292
|
+
};
|
|
293
|
+
readonly VECTORS_NOT_CONFIGURED: {
|
|
294
|
+
readonly status: 400;
|
|
295
|
+
readonly title: "Vector index introspector not configured";
|
|
296
|
+
};
|
|
297
|
+
readonly VECTOR_QUERY_UNSUPPORTED: {
|
|
298
|
+
readonly status: 400;
|
|
299
|
+
readonly title: "Vector index querying not enabled";
|
|
300
|
+
};
|
|
301
|
+
readonly WORKFLOWS_NOT_CONFIGURED: {
|
|
302
|
+
readonly status: 501;
|
|
303
|
+
readonly title: "Workflows not configured";
|
|
304
|
+
};
|
|
305
|
+
/** The auth/security audit read plane (`__lunora_admin__:getAuthAuditLog`). */
|
|
306
|
+
readonly AUTH_AUDIT_NOT_CONFIGURED: {
|
|
307
|
+
readonly status: 400;
|
|
308
|
+
readonly title: "Auth audit reader not configured";
|
|
309
|
+
};
|
|
310
|
+
/**
|
|
311
|
+
* Backend/DB failure reading the auth audit store. The throw site already
|
|
312
|
+
* keeps the message generic and logs the real error server-side only — flagged
|
|
313
|
+
* `internal: true` anyway as the deliberate posture for "a backend read
|
|
314
|
+
* failed", so a future edit that inlines the driver error can't leak it.
|
|
315
|
+
*/
|
|
316
|
+
readonly AUTH_AUDIT_READ_FAILED: {
|
|
317
|
+
readonly internal: true;
|
|
318
|
+
readonly status: 500;
|
|
319
|
+
readonly title: "Auth audit read failed";
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* Cron-job codes. The `*_NOT_STATIC` / `_INVALID` family are codegen
|
|
323
|
+
* build-time diagnostics — like `CODEGEN_DIAGNOSTIC`, they're thrown as plain
|
|
324
|
+
* messages into the CLI/Vite-overlay output, never cross the RPC wire, and are
|
|
325
|
+
* deliberately not `internal` (the message IS the fix). `CRON_JOB_FAILED` is
|
|
326
|
+
* the one runtime-reachable code in this family — its message interpolates
|
|
327
|
+
* binding/function/job names from the deployment, so it is flagged internal.
|
|
328
|
+
*/
|
|
329
|
+
readonly CRON_EXPR_INVALID: {
|
|
330
|
+
readonly status: 500;
|
|
331
|
+
readonly title: "Invalid cron expression";
|
|
332
|
+
};
|
|
333
|
+
readonly CRON_EXPR_NOT_STATIC: {
|
|
334
|
+
readonly status: 500;
|
|
335
|
+
readonly title: "Cron expression is not statically analyzable";
|
|
336
|
+
};
|
|
337
|
+
readonly CRON_JOB_FAILED: {
|
|
338
|
+
readonly internal: true;
|
|
339
|
+
readonly status: 500;
|
|
340
|
+
readonly title: "Cron job failed";
|
|
341
|
+
};
|
|
342
|
+
readonly CRON_NAME_NOT_STATIC: {
|
|
343
|
+
readonly status: 500;
|
|
344
|
+
readonly title: "Cron job name is not statically analyzable";
|
|
345
|
+
};
|
|
346
|
+
readonly CRON_NON_STATIC_FN: {
|
|
347
|
+
readonly status: 500;
|
|
348
|
+
readonly title: "Cron function reference is not statically analyzable";
|
|
349
|
+
};
|
|
350
|
+
readonly CRON_NON_STATIC_VALUE: {
|
|
351
|
+
readonly status: 500;
|
|
352
|
+
readonly title: "Cron value is not statically analyzable";
|
|
353
|
+
};
|
|
354
|
+
readonly CRON_SCHEDULE_NOT_STATIC: {
|
|
355
|
+
readonly status: 500;
|
|
356
|
+
readonly title: "Cron schedule is not statically analyzable";
|
|
357
|
+
};
|
|
358
|
+
readonly DUPLICATE_CRON_NAME: {
|
|
359
|
+
readonly status: 500;
|
|
360
|
+
readonly title: "Duplicate cron job name";
|
|
361
|
+
};
|
|
362
|
+
/** More codegen build-time diagnostics — see the cron-family comment above; same reasoning applies. */
|
|
363
|
+
readonly DUPLICATE_AGENT_BINDING: {
|
|
364
|
+
readonly status: 500;
|
|
365
|
+
readonly title: "Duplicate agent binding";
|
|
366
|
+
};
|
|
367
|
+
readonly DUPLICATE_AGENT_CLASS: {
|
|
368
|
+
readonly status: 500;
|
|
369
|
+
readonly title: "Duplicate agent generated class name";
|
|
370
|
+
};
|
|
371
|
+
readonly DUPLICATE_AGENT_NAME: {
|
|
372
|
+
readonly status: 500;
|
|
373
|
+
readonly title: "Duplicate agent name";
|
|
374
|
+
};
|
|
375
|
+
readonly DUPLICATE_MIGRATION_ID: {
|
|
376
|
+
readonly status: 500;
|
|
377
|
+
readonly title: "Duplicate migration id";
|
|
378
|
+
};
|
|
379
|
+
readonly DUPLICATE_QUEUE_BINDING: {
|
|
380
|
+
readonly status: 500;
|
|
381
|
+
readonly title: "Duplicate queue binding";
|
|
382
|
+
};
|
|
383
|
+
readonly DUPLICATE_QUEUE_NAME: {
|
|
384
|
+
readonly status: 500;
|
|
385
|
+
readonly title: "Duplicate queue name";
|
|
386
|
+
};
|
|
387
|
+
readonly DUPLICATE_WORKFLOW_CLASS: {
|
|
388
|
+
readonly status: 500;
|
|
389
|
+
readonly title: "Duplicate workflow generated class name";
|
|
390
|
+
};
|
|
391
|
+
readonly MIGRATION_ID_NOT_STATIC: {
|
|
392
|
+
readonly status: 500;
|
|
393
|
+
readonly title: "Migration id is not statically analyzable";
|
|
394
|
+
};
|
|
395
|
+
readonly NAMESPACE_COLLISION: {
|
|
396
|
+
readonly status: 500;
|
|
397
|
+
readonly title: "Function namespace collision";
|
|
398
|
+
};
|
|
399
|
+
/**
|
|
400
|
+
* `@lunora/runtime`'s dispatch/security-boundary codes — RPC/HTTP entry, not
|
|
401
|
+
* admin-gated. Fixed, non-sensitive messages throughout, so none are `internal`.
|
|
402
|
+
*/
|
|
403
|
+
readonly BAD_ROW: {
|
|
404
|
+
readonly status: 400;
|
|
405
|
+
readonly title: "Malformed import row";
|
|
406
|
+
};
|
|
407
|
+
readonly BAD_SUBSCRIPTION_ARGS: {
|
|
408
|
+
readonly status: 400;
|
|
409
|
+
readonly title: "Invalid subscription arguments";
|
|
410
|
+
};
|
|
411
|
+
readonly BATCH_LIMIT_EXCEEDED: {
|
|
412
|
+
readonly status: 400;
|
|
413
|
+
readonly title: "Batch limit exceeded";
|
|
414
|
+
};
|
|
415
|
+
readonly CROSS_SHARD_RANK_UNSUPPORTED: {
|
|
416
|
+
readonly status: 400;
|
|
417
|
+
readonly title: "Cross-shard rank() is unsupported";
|
|
418
|
+
};
|
|
419
|
+
readonly FORBIDDEN_FANOUT: {
|
|
420
|
+
readonly status: 403;
|
|
421
|
+
readonly title: "Fan-out forbidden";
|
|
422
|
+
};
|
|
423
|
+
readonly FORBIDDEN_ORIGIN: {
|
|
424
|
+
readonly status: 403;
|
|
425
|
+
readonly title: "Origin forbidden";
|
|
426
|
+
};
|
|
427
|
+
readonly FORBIDDEN_SHARD: {
|
|
428
|
+
readonly status: 403;
|
|
429
|
+
readonly title: "Shard access forbidden";
|
|
430
|
+
};
|
|
431
|
+
readonly GLOBAL_NOT_CONFIGURED: {
|
|
432
|
+
readonly status: 400;
|
|
433
|
+
readonly title: "Global table import not configured";
|
|
434
|
+
};
|
|
435
|
+
readonly INVALID_INPUT: {
|
|
436
|
+
readonly status: 400;
|
|
437
|
+
readonly title: "Invalid input";
|
|
438
|
+
};
|
|
439
|
+
readonly RATE_LIMITED: {
|
|
440
|
+
readonly status: 429;
|
|
441
|
+
readonly title: "Rate limited";
|
|
442
|
+
};
|
|
443
|
+
/** Thrown by `@lunora/auth` (Turnstile) and `@lunora/ratelimit` — an upstream dependency didn't respond. Fixed, safe message. */
|
|
444
|
+
readonly SERVICE_UNAVAILABLE: {
|
|
445
|
+
readonly status: 503;
|
|
446
|
+
readonly title: "Service unavailable";
|
|
447
|
+
};
|
|
448
|
+
readonly SHAPE_CROSS_SHARD_JOIN: {
|
|
449
|
+
readonly status: 400;
|
|
450
|
+
readonly title: "Shape cross-shard join is unsupported";
|
|
451
|
+
};
|
|
452
|
+
readonly UNAUTHENTICATED: {
|
|
453
|
+
readonly status: 401;
|
|
454
|
+
readonly title: "Unauthenticated";
|
|
455
|
+
};
|
|
456
|
+
readonly UNKNOWN_COLUMN: {
|
|
457
|
+
readonly status: 404;
|
|
458
|
+
readonly title: "Unknown column";
|
|
459
|
+
};
|
|
460
|
+
/**
|
|
461
|
+
* `@lunora/do`'s ShardDO — WebSocket-frame codes and SQLite-in-DO invariants.
|
|
462
|
+
* `NESTED_TRANSACTION` and `SQL_UNAVAILABLE` are "should never happen" state
|
|
463
|
+
* invariants (mirrors `RUN_DEPTH_EXCEEDED`'s posture above): today's message
|
|
464
|
+
* is static and safe, but flagged internal so a future edit that adds
|
|
465
|
+
* diagnostic detail can't accidentally start leaking it.
|
|
466
|
+
*/
|
|
467
|
+
readonly EXPIRED: {
|
|
468
|
+
readonly status: 404;
|
|
469
|
+
readonly title: "Session expired";
|
|
470
|
+
};
|
|
471
|
+
readonly NESTED_TRANSACTION: {
|
|
472
|
+
readonly internal: true;
|
|
473
|
+
readonly status: 500;
|
|
474
|
+
readonly title: "Nested transaction";
|
|
475
|
+
};
|
|
476
|
+
readonly OUT_OF_ORDER: {
|
|
477
|
+
readonly status: 409;
|
|
478
|
+
readonly title: "Out-of-order mutation";
|
|
479
|
+
};
|
|
480
|
+
readonly SHAPE_GLOBAL_TOO_LARGE: {
|
|
481
|
+
readonly status: 413;
|
|
482
|
+
readonly title: "Global shape too large";
|
|
483
|
+
};
|
|
484
|
+
readonly SHAPE_NOT_FOUND: {
|
|
485
|
+
readonly status: 404;
|
|
486
|
+
readonly title: "Shape not found";
|
|
487
|
+
};
|
|
488
|
+
readonly SQL_UNAVAILABLE: {
|
|
489
|
+
readonly internal: true;
|
|
490
|
+
readonly status: 500;
|
|
491
|
+
readonly title: "SQL storage unavailable";
|
|
492
|
+
};
|
|
493
|
+
readonly TOKEN_EXPIRED: {
|
|
494
|
+
readonly status: 401;
|
|
495
|
+
readonly title: "Authentication token expired";
|
|
496
|
+
};
|
|
497
|
+
readonly TOO_MANY_STREAMS: {
|
|
498
|
+
readonly status: 429;
|
|
499
|
+
readonly title: "Too many streams";
|
|
500
|
+
};
|
|
501
|
+
readonly UNKNOWN_ADMIN_OP: {
|
|
502
|
+
readonly status: 404;
|
|
503
|
+
readonly title: "Unknown admin operation";
|
|
504
|
+
};
|
|
505
|
+
/**
|
|
506
|
+
* `@lunora/shard-engine`'s relay hub (cross-shard shape relay coordination).
|
|
507
|
+
* Mirrors `SHARD_ERROR`/`SHARD_UNAVAILABLE` above: operational status for an
|
|
508
|
+
* app's own relay topology, not a secret — not `internal`.
|
|
509
|
+
*/
|
|
510
|
+
readonly RELAY_CANNOT_SEED: {
|
|
511
|
+
readonly status: 500;
|
|
512
|
+
readonly title: "Relay cannot seed";
|
|
513
|
+
};
|
|
514
|
+
readonly RELAY_MISCONFIGURED: {
|
|
515
|
+
readonly status: 500;
|
|
516
|
+
readonly title: "Relay misconfigured";
|
|
517
|
+
};
|
|
518
|
+
readonly RELAY_SEED_FAILED: {
|
|
519
|
+
readonly status: 502;
|
|
520
|
+
readonly title: "Relay seed failed";
|
|
521
|
+
};
|
|
522
|
+
/**
|
|
523
|
+
* A worker option required by the request path is absent (a deploy-config
|
|
524
|
+
* gap, not a caller error) — the fixed message names the missing option, so
|
|
525
|
+
* it's actionable and echoed. `MISCONFIGURED` is the one exception: its
|
|
526
|
+
* message interpolates the caller-supplied `functionPath`, and it's the code
|
|
527
|
+
* this plan's audit found live-leaking (`create-worker.ts`'s x402 gate).
|
|
528
|
+
*/
|
|
529
|
+
readonly MISCONFIGURED: {
|
|
530
|
+
readonly internal: true;
|
|
531
|
+
readonly status: 500;
|
|
532
|
+
readonly title: "Worker misconfigured";
|
|
533
|
+
};
|
|
534
|
+
/** `@lunora/nuxt`'s Nitro bridge: the request carried no Cloudflare bindings. Fixed, safe message. */
|
|
535
|
+
readonly LUNORA_RUNTIME_UNAVAILABLE: {
|
|
536
|
+
readonly status: 500;
|
|
537
|
+
readonly title: "Lunora runtime unavailable";
|
|
538
|
+
};
|
|
539
|
+
/**
|
|
540
|
+
* `@lunora/replica`'s event-log Durable Object: generic request-handler
|
|
541
|
+
* catch-all, mirroring `INTERNAL`/`INTERNAL_SERVER_ERROR`/`RPC_FAILED` above
|
|
542
|
+
* — the real error is logged server-side only, never in this code's message.
|
|
543
|
+
*/
|
|
544
|
+
readonly INTERNAL_ERROR: {
|
|
545
|
+
readonly internal: true;
|
|
546
|
+
readonly status: 500;
|
|
547
|
+
readonly title: "Internal error";
|
|
548
|
+
};
|
|
549
|
+
/**
|
|
550
|
+
* Client-SDK-only codes (`@lunora/client`), thrown locally in the browser/app
|
|
551
|
+
* process rather than by the server — `internal`'s wire-redaction semantics
|
|
552
|
+
* don't apply the same way here, since the "wire" is the app's own code
|
|
553
|
+
* catching its own client's exception. Kept in the catalog for the client's
|
|
554
|
+
* `code`-discrimination union and Studio/CLI rendering consistency.
|
|
555
|
+
*/
|
|
556
|
+
readonly BROWSER_TIMEOUT: {
|
|
557
|
+
readonly status: 504;
|
|
558
|
+
readonly title: "Browser operation timed out";
|
|
559
|
+
};
|
|
560
|
+
readonly CLIENT_CLOSED: {
|
|
561
|
+
readonly status: 400;
|
|
562
|
+
readonly title: "Client is closed";
|
|
563
|
+
};
|
|
564
|
+
readonly HTTP_STREAM_BAD_CHUNK: {
|
|
565
|
+
readonly status: 502;
|
|
566
|
+
readonly title: "Malformed HTTP stream chunk";
|
|
567
|
+
};
|
|
568
|
+
readonly HTTP_STREAM_INTERRUPTED: {
|
|
569
|
+
readonly status: 502;
|
|
570
|
+
readonly title: "HTTP stream interrupted";
|
|
571
|
+
};
|
|
572
|
+
readonly HTTP_STREAM_MISSING_PARAM: {
|
|
573
|
+
readonly status: 400;
|
|
574
|
+
readonly title: "HTTP stream missing path parameter";
|
|
575
|
+
};
|
|
576
|
+
readonly HTTP_STREAM_NO_BODY: {
|
|
577
|
+
readonly status: 502;
|
|
578
|
+
readonly title: "HTTP stream response has no body";
|
|
579
|
+
};
|
|
580
|
+
readonly HTTP_STREAM_STATUS: {
|
|
581
|
+
readonly status: 502;
|
|
582
|
+
readonly title: "HTTP stream request failed";
|
|
583
|
+
};
|
|
584
|
+
readonly HTTP_STREAM_TRANSPORT: {
|
|
585
|
+
readonly status: 502;
|
|
586
|
+
readonly title: "HTTP stream transport error";
|
|
587
|
+
};
|
|
588
|
+
readonly STREAM_BACKPRESSURE: {
|
|
589
|
+
readonly status: 429;
|
|
590
|
+
readonly title: "Stream backpressure";
|
|
591
|
+
};
|
|
592
|
+
readonly STREAM_DISCONNECTED: {
|
|
593
|
+
readonly status: 503;
|
|
594
|
+
readonly title: "Stream disconnected";
|
|
595
|
+
};
|
|
596
|
+
readonly STREAM_QUEUE_OVERFLOW: {
|
|
597
|
+
readonly status: 429;
|
|
598
|
+
readonly title: "Stream queue overflow";
|
|
599
|
+
};
|
|
600
|
+
/** `@lunora/db`'s offline outbox: a queued write targeted a collection removed/renamed in a later deploy. */
|
|
601
|
+
readonly UNKNOWN_MUTATION_FN: {
|
|
602
|
+
readonly status: 404;
|
|
603
|
+
readonly title: "Unknown mutation function";
|
|
604
|
+
};
|
|
174
605
|
};
|
|
175
606
|
/** A well-known Lunora error code (a key of {@link ERROR_CATALOG}). */
|
|
176
607
|
type LunoraErrorCode = keyof typeof ERROR_CATALOG;
|
|
177
608
|
/**
|
|
178
|
-
* True when `code` is an internal/redacted code — an internal failure or
|
|
179
|
-
* unhandled invariant whose `message` must NOT cross the wire (it may carry SQL
|
|
180
|
-
* fragments, file paths, or internal identifiers). Derived from the catalog's
|
|
181
|
-
* `internal` flag so the redaction posture stays in one place (the table).
|
|
182
|
-
* Throwing a `LunoraError` with any non-internal code is the author's vouch that
|
|
183
|
-
* its message is client-safe; an unknown/unregistered code is treated as safe.
|
|
184
|
-
*/
|
|
609
|
+
* True when `code` is an internal/redacted code — an internal failure or
|
|
610
|
+
* unhandled invariant whose `message` must NOT cross the wire (it may carry SQL
|
|
611
|
+
* fragments, file paths, or internal identifiers). Derived from the catalog's
|
|
612
|
+
* `internal` flag so the redaction posture stays in one place (the table).
|
|
613
|
+
* Throwing a `LunoraError` with any non-internal code is the author's vouch that
|
|
614
|
+
* its message is client-safe; an unknown/unregistered code is treated as safe.
|
|
615
|
+
*/
|
|
185
616
|
declare const isInternalCode: (code: string) => boolean;
|
|
186
617
|
/**
|
|
187
|
-
* A message-matched solution for errors that reach a consumer without a `code`
|
|
188
|
-
* — chiefly `@lunora/codegen` build errors, which are thrown as plain messages
|
|
189
|
-
* into generated code (and flattened to `{ message }` by the Vite overlay), so
|
|
190
|
-
* the message text is the only stable join key. Ordered most- to least-specific;
|
|
191
|
-
* the first matching rule wins.
|
|
192
|
-
*/
|
|
618
|
+
* A message-matched solution for errors that reach a consumer without a `code`
|
|
619
|
+
* — chiefly `@lunora/codegen` build errors, which are thrown as plain messages
|
|
620
|
+
* into generated code (and flattened to `{ message }` by the Vite overlay), so
|
|
621
|
+
* the message text is the only stable join key. Ordered most- to least-specific;
|
|
622
|
+
* the first matching rule wins.
|
|
623
|
+
*/
|
|
193
624
|
interface Solution {
|
|
194
625
|
/** Markdown body shown under the header. */
|
|
195
626
|
body: string;
|
|
@@ -204,27 +635,92 @@ interface SolutionRule extends Solution {
|
|
|
204
635
|
test: (message: string) => boolean;
|
|
205
636
|
}
|
|
206
637
|
/**
|
|
207
|
-
* Message-matched solutions (migrated verbatim from the former
|
|
208
|
-
* `@lunora/codegen` solutions table). Re-exported by `@lunora/codegen` as
|
|
209
|
-
* `LUNORA_SOLUTION_RULES` for backward compatibility.
|
|
210
|
-
*/
|
|
638
|
+
* Message-matched solutions (migrated verbatim from the former
|
|
639
|
+
* `@lunora/codegen` solutions table). Re-exported by `@lunora/codegen` as
|
|
640
|
+
* `LUNORA_SOLUTION_RULES` for backward compatibility.
|
|
641
|
+
*/
|
|
211
642
|
declare const MESSAGE_SOLUTIONS: ReadonlyArray<SolutionRule>;
|
|
212
643
|
/**
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
|
|
644
|
+
* One documented Cloudflare **platform** error — an edge/origin (5xx) or
|
|
645
|
+
* Cloudflare-service (1xxx) failure surfaced in an error *message* rather than
|
|
646
|
+
* thrown by Lunora as a coded `LunoraError`. These reach a Lunora app as
|
|
647
|
+
* plain text: a Worker that fetches a Cloudflare-fronted origin sees `Error 522`,
|
|
648
|
+
* a deploy that throws surfaces as `Error 1101`, and so on. The fields are the
|
|
649
|
+
* curated facts a grounded explainer elaborates on — never invents beyond.
|
|
650
|
+
*/
|
|
651
|
+
interface CloudflarePlatformError {
|
|
652
|
+
/** Documented likely causes (a short, comma-joined clause). */
|
|
653
|
+
causes: string;
|
|
654
|
+
/** The numeric Cloudflare error code, as it appears in the message (e.g. `"522"`, `"1101"`). */
|
|
655
|
+
code: string;
|
|
656
|
+
/** Canonical Cloudflare support-docs URL for this error's family. */
|
|
657
|
+
docsUrl: string;
|
|
658
|
+
/** Which docs family the code belongs to — shown in the "see docs" line. */
|
|
659
|
+
family: "1xxx" | "5xx";
|
|
660
|
+
/** The documented remediation. */
|
|
661
|
+
fix: string;
|
|
662
|
+
/** One-line summary of what the code means. */
|
|
663
|
+
summary: string;
|
|
664
|
+
/** Cloudflare's short name for the code (e.g. `"Connection timed out"`). */
|
|
665
|
+
title: string;
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* The curated Cloudflare platform-error table. Sourced from Cloudflare's official
|
|
669
|
+
* support docs — the codes surfaced to app authors on Workers/DO deployments (the
|
|
670
|
+
* origin-connection 52x family and the Worker/DNS/security 1xxx family). `1101`
|
|
671
|
+
* (a Worker threw) and `1102` (a Worker exceeded CPU) are the most Lunora-relevant.
|
|
672
|
+
*/
|
|
673
|
+
declare const CLOUDFLARE_PLATFORM_ERRORS: ReadonlyArray<CloudflarePlatformError>;
|
|
674
|
+
/**
|
|
675
|
+
* Recognize a Cloudflare platform-error {@link CloudflarePlatformError} in a raw
|
|
676
|
+
* error message, conservatively: the message must carry Cloudflare's own
|
|
677
|
+
* `Error <code>` phrasing, or mention `cloudflare` alongside the standalone
|
|
678
|
+
* code. That keeps a bare number (`expected 520 items`) from false-matching a 5xx
|
|
679
|
+
* code, at the cost of missing a context-free code — the safe trade for a
|
|
680
|
+
* grounded hint. Returns the matched code's {@link Solution}, or `undefined`.
|
|
681
|
+
*
|
|
682
|
+
* Matching runs in two passes, strongest first: Cloudflare's own `Error <code>`
|
|
683
|
+
* phrasing is unambiguous, so it must win over the weaker "mentions cloudflare
|
|
684
|
+
* near some number" heuristic regardless of table order. A single pass let a weak
|
|
685
|
+
* match on an earlier entry beat an explicit match on a later one — `"Cloudflare
|
|
686
|
+
* Error 1102: exceeded after 524 ms"` resolved to 524, and that wrong grounded
|
|
687
|
+
* fix is exactly what the explainer prompt is built from.
|
|
688
|
+
*/
|
|
689
|
+
declare const findCloudflarePlatformSolution: (message: string) => Solution | undefined;
|
|
690
|
+
/**
|
|
691
|
+
* Flatten a Markdown hint to plain text for a terminal / non-Markdown surface:
|
|
692
|
+
* drop code-fence markers and strip inline `**bold**` / `` `code` `` emphasis.
|
|
693
|
+
* Shared by the CLI renderer and the Studio `ErrorAlert` so the two can't drift.
|
|
694
|
+
*/
|
|
217
695
|
declare const flattenHint: (hint: ErrorHint) => string;
|
|
218
696
|
/**
|
|
219
|
-
* Find the first message-matched {@link Solution} for `message`, or `undefined`
|
|
220
|
-
* if none recognize it. Re-exported by `@lunora/codegen` as `findLunoraSolution`.
|
|
221
|
-
*/
|
|
697
|
+
* Find the first message-matched {@link Solution} for `message`, or `undefined`
|
|
698
|
+
* if none recognize it. Re-exported by `@lunora/codegen` as `findLunoraSolution`.
|
|
699
|
+
*/
|
|
222
700
|
declare const findSolutionByMessage: (message: string) => Solution | undefined;
|
|
223
701
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
* `
|
|
227
|
-
|
|
702
|
+
* Find a solution for `message` across BOTH Lunora's own rules and the curated
|
|
703
|
+
* Cloudflare platform-error table — the lookup the Studio Issues panel and the
|
|
704
|
+
* `explainIssue` grounding use.
|
|
705
|
+
*
|
|
706
|
+
* Deliberately separate from {@link findSolutionByMessage} rather than folded into
|
|
707
|
+
* it. That function is on `resolveHint`, and therefore on `toErrorBody` — the
|
|
708
|
+
* envelope builder for every failed request. Most `ERROR_CATALOG` entries
|
|
709
|
+
* carry no `hint`, so folding the platform table in there meant an ordinary
|
|
710
|
+
* `BAD_REQUEST` whose message merely mentioned "cloudflare" near a number shipped
|
|
711
|
+
* zone-configuration guidance ("review the zone's Firewall/WAF and IP Access
|
|
712
|
+
* Rules") to unauthenticated browsers. The same fold put the table on the CLI
|
|
713
|
+
* renderer and the Vite overlay, and on `toErrorBody`'s hot path.
|
|
714
|
+
*
|
|
715
|
+
* Platform errors are operator-facing context for an already-persisted Issue, so
|
|
716
|
+
* the operator-facing surfaces opt in here and the wire path stays Lunora-only.
|
|
717
|
+
*/
|
|
718
|
+
declare const findIssueSolution: (message: string) => Solution | undefined;
|
|
719
|
+
/**
|
|
720
|
+
* Resolve an actionable hint for an error: prefer a hint carried on the error
|
|
721
|
+
* (or its `code`'s catalog entry), then fall back to a message match. Returns
|
|
722
|
+
* `undefined` when nothing recognizes it.
|
|
723
|
+
*/
|
|
228
724
|
declare const resolveHint: (input: {
|
|
229
725
|
code?: string;
|
|
230
726
|
hint?: ErrorHint;
|
|
@@ -256,16 +752,16 @@ interface LunoraErrorOptions {
|
|
|
256
752
|
title?: string;
|
|
257
753
|
}
|
|
258
754
|
/**
|
|
259
|
-
* A code string: a well-known {@link LunoraErrorCode} (with autocomplete) or any
|
|
260
|
-
* package-specific code not yet in the catalog.
|
|
261
|
-
*/
|
|
755
|
+
* A code string: a well-known {@link LunoraErrorCode} (with autocomplete) or any
|
|
756
|
+
* package-specific code not yet in the catalog.
|
|
757
|
+
*/
|
|
262
758
|
type LunoraErrorCodeInput = LunoraErrorCode | (string & {});
|
|
263
759
|
declare class LunoraError extends Error {
|
|
264
760
|
/**
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
761
|
+
* Discriminator recognised by `@visulima/error`'s `renderError`/`isVisulimaError`
|
|
762
|
+
* (`error.type === "VisulimaError"`), so a `LunoraError` renders like a native
|
|
763
|
+
* `VisulimaError` — hint and all.
|
|
764
|
+
*/
|
|
269
765
|
readonly type = "VisulimaError";
|
|
270
766
|
/** Actionable fix (Markdown), rendered by the CLI/overlay/Studio. */
|
|
271
767
|
readonly hint: ErrorHint | undefined;
|
|
@@ -273,7 +769,7 @@ declare class LunoraError extends Error {
|
|
|
273
769
|
readonly title: string | undefined;
|
|
274
770
|
/** Source location, when known (mirrors `VisulimaError.loc`). */
|
|
275
771
|
readonly loc: ErrorLocation | undefined;
|
|
276
|
-
/** Machine-readable reason, keyed into
|
|
772
|
+
/** Machine-readable reason, keyed into `ERROR_CATALOG`. */
|
|
277
773
|
readonly code: string;
|
|
278
774
|
/** HTTP/RPC status for the transport mappers. */
|
|
279
775
|
readonly status: number;
|
|
@@ -290,8 +786,15 @@ interface LunoraErrorLike extends Error {
|
|
|
290
786
|
docsUrl?: string;
|
|
291
787
|
hint?: ErrorHint;
|
|
292
788
|
status: number;
|
|
789
|
+
/** Wire brand that distinguishes real `LunoraError`s from foreign errors. */
|
|
790
|
+
type: "VisulimaError";
|
|
293
791
|
}
|
|
294
|
-
/**
|
|
792
|
+
/**
|
|
793
|
+
* True when `error` carries the Lunora transport shape (string `code` + numeric
|
|
794
|
+
* `status` + the `VisulimaError` brand). The `type` brand is what distinguishes
|
|
795
|
+
* a real `LunoraError` (or its wire-decoded twin) from a foreign error that
|
|
796
|
+
* happens to carry `code`/`status` — see plan 119 for the full rationale.
|
|
797
|
+
*/
|
|
295
798
|
declare const isLunoraError: (error: unknown) => error is LunoraErrorLike;
|
|
296
799
|
/** Throw an `INTERNAL` {@link LunoraError} when `condition` is falsy. */
|
|
297
800
|
declare const invariant: (condition: unknown, message: string) => asserts condition;
|
|
@@ -307,9 +810,9 @@ interface ErrorBody {
|
|
|
307
810
|
}
|
|
308
811
|
interface ToErrorBodyOptions {
|
|
309
812
|
/**
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
813
|
+
* Wire-encode a `LunoraError`'s structured `data` for the client (so a
|
|
814
|
+
* `bigint`/`bytes` inside it survives). Omit to drop `data` from the body.
|
|
815
|
+
*/
|
|
313
816
|
encodeData?: (data: unknown) => unknown;
|
|
314
817
|
/** Code for an unrecognized (non-`LunoraError`) throw. Default `"INTERNAL"`. */
|
|
315
818
|
fallbackCode?: string;
|
|
@@ -324,12 +827,12 @@ interface ToErrorBodyResult {
|
|
|
324
827
|
status: number;
|
|
325
828
|
}
|
|
326
829
|
/**
|
|
327
|
-
* Turn a thrown value into an {@link ErrorBody} + status, applying the redaction
|
|
328
|
-
* invariant. A `LunoraError` with a non-internal code is echoed with its
|
|
329
|
-
* `message`, resolved `hint`, `docsUrl`, and (when `encodeData` is given) its
|
|
330
|
-
* `data`. An internal-coded `LunoraError` keeps its `code`/`status` but its
|
|
331
|
-
* message is replaced with `redactedMessage`. Anything else becomes a generic
|
|
332
|
-
* `fallbackCode`/500. When `redacted` is `true`, log the raw error server-side.
|
|
333
|
-
*/
|
|
830
|
+
* Turn a thrown value into an {@link ErrorBody} + status, applying the redaction
|
|
831
|
+
* invariant. A `LunoraError` with a non-internal code is echoed with its
|
|
832
|
+
* `message`, resolved `hint`, `docsUrl`, and (when `encodeData` is given) its
|
|
833
|
+
* `data`. An internal-coded `LunoraError` keeps its `code`/`status` but its
|
|
834
|
+
* message is replaced with `redactedMessage`. Anything else becomes a generic
|
|
835
|
+
* `fallbackCode`/500. When `redacted` is `true`, log the raw error server-side.
|
|
836
|
+
*/
|
|
334
837
|
declare const toErrorBody: (error: unknown, options?: ToErrorBodyOptions) => ToErrorBodyResult;
|
|
335
|
-
export { ERROR_CATALOG, type ErrorBody, type ErrorCatalogEntry, type ErrorHint, type ErrorLocation, LunoraError, type LunoraErrorCode, type LunoraErrorCodeInput, type LunoraErrorLike, type LunoraErrorOptions, MESSAGE_SOLUTIONS, type Solution, type SolutionRule, type ToErrorBodyOptions, type ToErrorBodyResult, findSolutionByMessage, flattenHint, invariant, isInternalCode, isLunoraError, resolveHint, toErrorBody, unreachable };
|
|
838
|
+
export { CLOUDFLARE_PLATFORM_ERRORS, type CloudflarePlatformError, ERROR_CATALOG, type ErrorBody, type ErrorCatalogEntry, type ErrorHint, type ErrorLocation, LunoraError, type LunoraErrorCode, type LunoraErrorCodeInput, type LunoraErrorLike, type LunoraErrorOptions, MESSAGE_SOLUTIONS, type Solution, type SolutionRule, type ToErrorBodyOptions, type ToErrorBodyResult, findCloudflarePlatformSolution, findIssueSolution, findSolutionByMessage, flattenHint, invariant, isInternalCode, isLunoraError, resolveHint, toErrorBody, unreachable };
|