@deployanyway/error-translator 0.2.0 → 0.4.0
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/CHANGELOG.md +14 -0
- package/MIGRATION.md +11 -0
- package/README.md +109 -8
- package/bin/cli.js +1 -37
- package/dist/index.cjs +725 -0
- package/index.d.cts +25 -0
- package/index.d.ts +25 -0
- package/package.json +40 -9
- package/src/cli.js +74 -0
- package/src/definitions.js +2 -0
- package/src/extra-definitions.js +494 -0
- package/src/index.js +62 -0
- package/src/input.js +15 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.js
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
errorCatalog: () => errorCatalog,
|
|
24
|
+
listErrors: () => listErrors,
|
|
25
|
+
renderTranslation: () => renderTranslation,
|
|
26
|
+
translateError: () => translateError,
|
|
27
|
+
translateErrors: () => translateErrors
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
|
|
31
|
+
// src/extra-definitions.js
|
|
32
|
+
var extraDefinitions = {
|
|
33
|
+
EACCES: {
|
|
34
|
+
title: "Permission denied",
|
|
35
|
+
explanation: "The process lacks permission for the requested operation.",
|
|
36
|
+
likelyCauses: [
|
|
37
|
+
"A directory or file belongs to another account",
|
|
38
|
+
"The application runs under a restricted service identity"
|
|
39
|
+
],
|
|
40
|
+
suggestions: [
|
|
41
|
+
"Check the service identity and permissions on each parent directory.",
|
|
42
|
+
"Grant only the access the application needs; avoid running everything as administrator."
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
EPERM: {
|
|
46
|
+
title: "Operation not permitted",
|
|
47
|
+
explanation: "The operating system rejected an operation even though the target may exist.",
|
|
48
|
+
likelyCauses: [
|
|
49
|
+
"A protected resource or locked file",
|
|
50
|
+
"An operation forbidden by the current platform or identity"
|
|
51
|
+
],
|
|
52
|
+
suggestions: [
|
|
53
|
+
"Inspect the operation, ownership and platform restrictions.",
|
|
54
|
+
"Close the process holding the resource and retry only if the operation is intended."
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
EEXIST: {
|
|
58
|
+
title: "Target already exists",
|
|
59
|
+
explanation: "A creation operation requires a new target, but that target already exists.",
|
|
60
|
+
likelyCauses: ["A repeated initialization step", "A filename collision"],
|
|
61
|
+
suggestions: [
|
|
62
|
+
"Check the target before creating it and make initialization idempotent.",
|
|
63
|
+
"Use a distinct name rather than deleting an existing target blindly."
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
ENOTDIR: {
|
|
67
|
+
title: "Expected a directory",
|
|
68
|
+
explanation: "A path component used as a directory is actually another kind of file.",
|
|
69
|
+
likelyCauses: [
|
|
70
|
+
"A file appears in the middle of the path",
|
|
71
|
+
"A configuration value points to the wrong target"
|
|
72
|
+
],
|
|
73
|
+
suggestions: [
|
|
74
|
+
"Inspect each path component and its type.",
|
|
75
|
+
"Correct the directory configuration before retrying."
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
EISDIR: {
|
|
79
|
+
title: "Expected a file",
|
|
80
|
+
explanation: "The operation received a directory where it expected a file.",
|
|
81
|
+
likelyCauses: [
|
|
82
|
+
"The filename is missing from a configured path",
|
|
83
|
+
"A directory was passed to a file operation"
|
|
84
|
+
],
|
|
85
|
+
suggestions: [
|
|
86
|
+
"Check the complete path and inspect the target type.",
|
|
87
|
+
"Use the appropriate directory API when working with directories."
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
ENOTEMPTY: {
|
|
91
|
+
title: "Directory is not empty",
|
|
92
|
+
explanation: "A directory operation requires an empty target, but entries remain.",
|
|
93
|
+
likelyCauses: [
|
|
94
|
+
"Generated files remain in the directory",
|
|
95
|
+
"Another process is still writing files"
|
|
96
|
+
],
|
|
97
|
+
suggestions: [
|
|
98
|
+
"List the remaining entries and identify their owner.",
|
|
99
|
+
"Remove only confirmed disposable content or choose a new directory."
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
EMFILE: {
|
|
103
|
+
title: "Too many open files",
|
|
104
|
+
explanation: "The process has exhausted its available file descriptors.",
|
|
105
|
+
likelyCauses: [
|
|
106
|
+
"Handles are not closed",
|
|
107
|
+
"Too many files or sockets are opened concurrently"
|
|
108
|
+
],
|
|
109
|
+
suggestions: [
|
|
110
|
+
"Close handles in cleanup paths and bound concurrent work.",
|
|
111
|
+
"Inspect descriptor usage before considering a higher process limit."
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
ENFILE: {
|
|
115
|
+
title: "System file table exhausted",
|
|
116
|
+
explanation: "The system cannot allocate another file handle.",
|
|
117
|
+
likelyCauses: [
|
|
118
|
+
"Many processes hold open files",
|
|
119
|
+
"The host has reached a system resource limit"
|
|
120
|
+
],
|
|
121
|
+
suggestions: [
|
|
122
|
+
"Inspect host-wide handle usage and identify runaway processes.",
|
|
123
|
+
"Reduce concurrency and resolve leaks before changing system limits."
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
ENOSPC: {
|
|
127
|
+
title: "No space left",
|
|
128
|
+
explanation: "The filesystem cannot allocate the space or resources required by the operation.",
|
|
129
|
+
likelyCauses: [
|
|
130
|
+
"The volume is full",
|
|
131
|
+
"Filesystem quotas or resource limits are exhausted"
|
|
132
|
+
],
|
|
133
|
+
suggestions: [
|
|
134
|
+
"Check free space, quotas and the volume receiving the write.",
|
|
135
|
+
"Clear verified disposable data and investigate rapid growth."
|
|
136
|
+
]
|
|
137
|
+
},
|
|
138
|
+
EROFS: {
|
|
139
|
+
title: "Read-only filesystem",
|
|
140
|
+
explanation: "The target filesystem does not permit writes.",
|
|
141
|
+
likelyCauses: [
|
|
142
|
+
"A read-only container mount",
|
|
143
|
+
"A protected or recovery-mounted volume"
|
|
144
|
+
],
|
|
145
|
+
suggestions: [
|
|
146
|
+
"Inspect mount settings and choose an intended writable data location.",
|
|
147
|
+
"Change mount configuration only when the write is part of the deployment design."
|
|
148
|
+
]
|
|
149
|
+
},
|
|
150
|
+
EBUSY: {
|
|
151
|
+
title: "Resource busy",
|
|
152
|
+
explanation: "A resource cannot complete the requested operation while another operation holds it.",
|
|
153
|
+
likelyCauses: [
|
|
154
|
+
"A mounted or open resource",
|
|
155
|
+
"A concurrent operation has not finished"
|
|
156
|
+
],
|
|
157
|
+
suggestions: [
|
|
158
|
+
"Identify the process or operation holding the resource.",
|
|
159
|
+
"Wait for its completion or coordinate ownership instead of looping without a limit."
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
EXDEV: {
|
|
163
|
+
title: "Cross-device operation",
|
|
164
|
+
explanation: "An operation such as a rename crosses filesystem boundaries that it cannot cross directly.",
|
|
165
|
+
likelyCauses: [
|
|
166
|
+
"Temporary and destination files live on different volumes",
|
|
167
|
+
"A container mount creates a filesystem boundary"
|
|
168
|
+
],
|
|
169
|
+
suggestions: [
|
|
170
|
+
"Create temporary files on the destination filesystem when atomic rename is required.",
|
|
171
|
+
"Use an intentional copy-and-cleanup workflow when atomic movement is unnecessary."
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
EPIPE: {
|
|
175
|
+
title: "Broken pipe",
|
|
176
|
+
explanation: "The application wrote to a stream whose receiving end has closed.",
|
|
177
|
+
likelyCauses: [
|
|
178
|
+
"A downstream command exited",
|
|
179
|
+
"A peer disconnected before the write completed"
|
|
180
|
+
],
|
|
181
|
+
suggestions: [
|
|
182
|
+
"Handle stream errors and stop producing data when the consumer closes.",
|
|
183
|
+
"Distinguish an expected pipeline close from an unexpected connection failure."
|
|
184
|
+
]
|
|
185
|
+
},
|
|
186
|
+
ECONNRESET: {
|
|
187
|
+
title: "Connection reset",
|
|
188
|
+
explanation: "A connection was forcibly closed while the application was using it.",
|
|
189
|
+
likelyCauses: [
|
|
190
|
+
"The remote peer closed the connection",
|
|
191
|
+
"An intermediary interrupted the session"
|
|
192
|
+
],
|
|
193
|
+
suggestions: [
|
|
194
|
+
"Inspect peer logs, timeout settings and recent connection changes.",
|
|
195
|
+
"Retry only safe operations with a bounded backoff and avoid duplicate side effects."
|
|
196
|
+
]
|
|
197
|
+
},
|
|
198
|
+
ETIMEDOUT: {
|
|
199
|
+
title: "Operation timed out",
|
|
200
|
+
explanation: "A connection or operation did not finish within its allowed time.",
|
|
201
|
+
likelyCauses: [
|
|
202
|
+
"An unreachable or slow peer",
|
|
203
|
+
"A timeout shorter than the expected operation"
|
|
204
|
+
],
|
|
205
|
+
suggestions: [
|
|
206
|
+
"Check network reachability, service latency and the configured timeout.",
|
|
207
|
+
"Use bounded retries only for operations that are safe to repeat."
|
|
208
|
+
]
|
|
209
|
+
},
|
|
210
|
+
ENOTFOUND: {
|
|
211
|
+
title: "Name lookup failed",
|
|
212
|
+
explanation: "The requested hostname could not be resolved by the lookup operation.",
|
|
213
|
+
likelyCauses: [
|
|
214
|
+
"A misspelled hostname",
|
|
215
|
+
"Resolver configuration or lookup resources failed"
|
|
216
|
+
],
|
|
217
|
+
suggestions: [
|
|
218
|
+
"Check the exact hostname and DNS behavior from the same runtime environment.",
|
|
219
|
+
"Do not assume every lookup failure proves the hostname does not exist."
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
EAI_AGAIN: {
|
|
223
|
+
title: "Temporary name lookup failure",
|
|
224
|
+
explanation: "Name resolution reported a temporary failure.",
|
|
225
|
+
likelyCauses: [
|
|
226
|
+
"A resolver is temporarily unavailable",
|
|
227
|
+
"A transient network or DNS problem"
|
|
228
|
+
],
|
|
229
|
+
suggestions: [
|
|
230
|
+
"Check the resolver and network from the affected host.",
|
|
231
|
+
"Apply bounded retry with backoff and report persistent failures."
|
|
232
|
+
]
|
|
233
|
+
},
|
|
234
|
+
EADDRNOTAVAIL: {
|
|
235
|
+
title: "Local address unavailable",
|
|
236
|
+
explanation: "The application tried to use an address that is not available on the local system.",
|
|
237
|
+
likelyCauses: [
|
|
238
|
+
"Binding to an address on another host",
|
|
239
|
+
"An interface address changed"
|
|
240
|
+
],
|
|
241
|
+
suggestions: [
|
|
242
|
+
"Inspect local interfaces and the configured bind address.",
|
|
243
|
+
"Use the intended local interface rather than a remote destination address."
|
|
244
|
+
]
|
|
245
|
+
},
|
|
246
|
+
ECONNABORTED: {
|
|
247
|
+
title: "Connection aborted",
|
|
248
|
+
explanation: "A connection was aborted before the operation completed.",
|
|
249
|
+
likelyCauses: [
|
|
250
|
+
"A connection failure during setup or transfer",
|
|
251
|
+
"A local or intermediary cancellation"
|
|
252
|
+
],
|
|
253
|
+
suggestions: [
|
|
254
|
+
"Inspect the failure timing and both ends of the connection.",
|
|
255
|
+
"Handle cancellation separately from application errors when appropriate."
|
|
256
|
+
]
|
|
257
|
+
},
|
|
258
|
+
ENETUNREACH: {
|
|
259
|
+
title: "Network unreachable",
|
|
260
|
+
explanation: "The host has no usable route to the requested network.",
|
|
261
|
+
likelyCauses: [
|
|
262
|
+
"Missing route or disconnected interface",
|
|
263
|
+
"Network isolation in a container or host"
|
|
264
|
+
],
|
|
265
|
+
suggestions: [
|
|
266
|
+
"Inspect connectivity and routing in the application environment.",
|
|
267
|
+
"Confirm the destination network is intended to be reachable."
|
|
268
|
+
]
|
|
269
|
+
},
|
|
270
|
+
EHOSTUNREACH: {
|
|
271
|
+
title: "Host unreachable",
|
|
272
|
+
explanation: "The destination host could not be reached through the available network path.",
|
|
273
|
+
likelyCauses: [
|
|
274
|
+
"The destination is unavailable",
|
|
275
|
+
"Routing or filtering blocks the path"
|
|
276
|
+
],
|
|
277
|
+
suggestions: [
|
|
278
|
+
"Check the destination address and routing from the affected host.",
|
|
279
|
+
"Inspect network policy rather than disabling protection blindly."
|
|
280
|
+
]
|
|
281
|
+
},
|
|
282
|
+
EINVAL: {
|
|
283
|
+
title: "Invalid argument",
|
|
284
|
+
explanation: "The operating system rejected an argument to the operation.",
|
|
285
|
+
likelyCauses: [
|
|
286
|
+
"A value outside the operation contract",
|
|
287
|
+
"A platform-specific unsupported value"
|
|
288
|
+
],
|
|
289
|
+
suggestions: [
|
|
290
|
+
"Inspect the syscall and the exact values passed to it.",
|
|
291
|
+
"Validate values against the API and platform requirements."
|
|
292
|
+
]
|
|
293
|
+
},
|
|
294
|
+
ABORT_ERR: {
|
|
295
|
+
title: "Operation aborted",
|
|
296
|
+
explanation: "An operation was cancelled through an abort mechanism.",
|
|
297
|
+
likelyCauses: [
|
|
298
|
+
"An AbortSignal was triggered",
|
|
299
|
+
"A caller timeout cancelled the operation"
|
|
300
|
+
],
|
|
301
|
+
suggestions: [
|
|
302
|
+
"Inspect who owns the abort controller and when cancellation occurred.",
|
|
303
|
+
"Treat expected cancellation separately and clean up resources."
|
|
304
|
+
]
|
|
305
|
+
},
|
|
306
|
+
ERR_INVALID_ARG_TYPE: {
|
|
307
|
+
title: "Wrong argument type",
|
|
308
|
+
explanation: "A Node API received an argument of the wrong type.",
|
|
309
|
+
likelyCauses: [
|
|
310
|
+
"A missing or incorrect value",
|
|
311
|
+
"An unexpected return type passed to another API"
|
|
312
|
+
],
|
|
313
|
+
suggestions: [
|
|
314
|
+
"Read the parameter name in the error and inspect its actual value.",
|
|
315
|
+
"Validate the argument at the boundary where it enters your application."
|
|
316
|
+
]
|
|
317
|
+
},
|
|
318
|
+
ERR_INVALID_ARG_VALUE: {
|
|
319
|
+
title: "Invalid argument value",
|
|
320
|
+
explanation: "An argument has a value the API does not accept.",
|
|
321
|
+
likelyCauses: [
|
|
322
|
+
"A valid type with an unsupported value",
|
|
323
|
+
"An invalid option combination"
|
|
324
|
+
],
|
|
325
|
+
suggestions: [
|
|
326
|
+
"Inspect the named parameter and documented accepted values.",
|
|
327
|
+
"Validate options before calling the API."
|
|
328
|
+
]
|
|
329
|
+
},
|
|
330
|
+
ERR_OUT_OF_RANGE: {
|
|
331
|
+
title: "Value outside allowed range",
|
|
332
|
+
explanation: "A numeric or size argument falls outside the API range.",
|
|
333
|
+
likelyCauses: [
|
|
334
|
+
"An invalid offset or length",
|
|
335
|
+
"A computed limit exceeds the supported bounds"
|
|
336
|
+
],
|
|
337
|
+
suggestions: [
|
|
338
|
+
"Check the reported minimum and maximum and the calculation producing the value.",
|
|
339
|
+
"Add boundary tests for zero, limits and oversized input."
|
|
340
|
+
]
|
|
341
|
+
},
|
|
342
|
+
ERR_HTTP_HEADERS_SENT: {
|
|
343
|
+
title: "Headers already sent",
|
|
344
|
+
explanation: "The server tried to change headers after the response headers had been sent.",
|
|
345
|
+
likelyCauses: [
|
|
346
|
+
"Two code paths respond to the same request",
|
|
347
|
+
"An asynchronous callback runs after the response is complete"
|
|
348
|
+
],
|
|
349
|
+
suggestions: [
|
|
350
|
+
"Trace every response path and return after sending the response.",
|
|
351
|
+
"Coordinate asynchronous work so only one path owns the final response."
|
|
352
|
+
]
|
|
353
|
+
},
|
|
354
|
+
ERR_HTTP_INVALID_STATUS_CODE: {
|
|
355
|
+
title: "Invalid HTTP status",
|
|
356
|
+
explanation: "The response status code is outside the accepted API range.",
|
|
357
|
+
likelyCauses: [
|
|
358
|
+
"An undefined value becomes a status",
|
|
359
|
+
"A business code is mistaken for an HTTP status"
|
|
360
|
+
],
|
|
361
|
+
suggestions: [
|
|
362
|
+
"Check the status value before assigning or sending it.",
|
|
363
|
+
"Keep internal result codes separate from HTTP status codes."
|
|
364
|
+
]
|
|
365
|
+
},
|
|
366
|
+
ERR_INVALID_URL: {
|
|
367
|
+
title: "Invalid URL",
|
|
368
|
+
explanation: "The URL parser cannot interpret the supplied URL.",
|
|
369
|
+
likelyCauses: [
|
|
370
|
+
"A malformed absolute URL",
|
|
371
|
+
"A relative URL without a valid base"
|
|
372
|
+
],
|
|
373
|
+
suggestions: [
|
|
374
|
+
"Inspect the original input and supply an explicit base for relative paths.",
|
|
375
|
+
"Validate user-controlled URL inputs before making requests."
|
|
376
|
+
]
|
|
377
|
+
},
|
|
378
|
+
ERR_PACKAGE_PATH_NOT_EXPORTED: {
|
|
379
|
+
title: "Package path not exported",
|
|
380
|
+
explanation: "A package exports map does not expose the requested subpath.",
|
|
381
|
+
likelyCauses: [
|
|
382
|
+
"Importing an internal package file",
|
|
383
|
+
"A dependency changed its public entry points"
|
|
384
|
+
],
|
|
385
|
+
suggestions: [
|
|
386
|
+
"Inspect the package exports and use a documented public entry.",
|
|
387
|
+
"Upgrade or pin compatible dependencies instead of relying on private paths."
|
|
388
|
+
]
|
|
389
|
+
},
|
|
390
|
+
ERR_PACKAGE_IMPORT_NOT_DEFINED: {
|
|
391
|
+
title: "Package import not defined",
|
|
392
|
+
explanation: "A package imports map has no matching internal specifier.",
|
|
393
|
+
likelyCauses: [
|
|
394
|
+
"A missing imports mapping",
|
|
395
|
+
"A specifier is used outside its intended package scope"
|
|
396
|
+
],
|
|
397
|
+
suggestions: [
|
|
398
|
+
"Check package.json imports and the exact specifier.",
|
|
399
|
+
"Keep internal import aliases inside the package that defines them."
|
|
400
|
+
]
|
|
401
|
+
},
|
|
402
|
+
ERR_INVALID_PACKAGE_CONFIG: {
|
|
403
|
+
title: "Invalid package configuration",
|
|
404
|
+
explanation: "Node could not use the package configuration.",
|
|
405
|
+
likelyCauses: ["Malformed package.json", "An invalid configuration field"],
|
|
406
|
+
suggestions: [
|
|
407
|
+
"Read the named package.json and validate its JSON and relevant fields.",
|
|
408
|
+
"Check the first configuration error before reinstalling dependencies."
|
|
409
|
+
]
|
|
410
|
+
},
|
|
411
|
+
ERR_UNKNOWN_FILE_EXTENSION: {
|
|
412
|
+
title: "Unknown module file extension",
|
|
413
|
+
explanation: "The module loader does not recognize the file extension in this context.",
|
|
414
|
+
likelyCauses: [
|
|
415
|
+
"An unsupported file type is imported",
|
|
416
|
+
"The required build or loader is missing"
|
|
417
|
+
],
|
|
418
|
+
suggestions: [
|
|
419
|
+
"Check the imported extension and the runtime module configuration.",
|
|
420
|
+
"Compile to a supported format or use a documented loader setup."
|
|
421
|
+
]
|
|
422
|
+
},
|
|
423
|
+
ERR_IMPORT_ATTRIBUTE_MISSING: {
|
|
424
|
+
title: "Required import attribute missing",
|
|
425
|
+
explanation: "A module import requires an attribute that was not provided.",
|
|
426
|
+
likelyCauses: [
|
|
427
|
+
"A JSON import lacks the required type attribute",
|
|
428
|
+
"An import was copied from a different runtime version"
|
|
429
|
+
],
|
|
430
|
+
suggestions: [
|
|
431
|
+
"Check the module type and import syntax for your supported Node version.",
|
|
432
|
+
"Use the required import attributes or an appropriate file-reading API."
|
|
433
|
+
]
|
|
434
|
+
},
|
|
435
|
+
ERR_STREAM_WRITE_AFTER_END: {
|
|
436
|
+
title: "Write after stream end",
|
|
437
|
+
explanation: "Data was written after the writable stream had ended.",
|
|
438
|
+
likelyCauses: [
|
|
439
|
+
"A late callback writes to a closed stream",
|
|
440
|
+
"Multiple owners end and write the same stream"
|
|
441
|
+
],
|
|
442
|
+
suggestions: [
|
|
443
|
+
"Trace the stream lifecycle and coordinate the writer with completion.",
|
|
444
|
+
"Test delayed callbacks and ensure end is called once work is complete."
|
|
445
|
+
]
|
|
446
|
+
},
|
|
447
|
+
ERR_STREAM_DESTROYED: {
|
|
448
|
+
title: "Stream destroyed",
|
|
449
|
+
explanation: "An operation used a stream after it had been destroyed.",
|
|
450
|
+
likelyCauses: [
|
|
451
|
+
"A prior error destroyed the stream",
|
|
452
|
+
"Cleanup ran while work was still pending"
|
|
453
|
+
],
|
|
454
|
+
suggestions: [
|
|
455
|
+
"Inspect the original stream error and cancellation timing.",
|
|
456
|
+
"Stop dependent work when the stream closes or is destroyed."
|
|
457
|
+
]
|
|
458
|
+
},
|
|
459
|
+
ERR_SOCKET_BAD_PORT: {
|
|
460
|
+
title: "Invalid socket port",
|
|
461
|
+
explanation: "A socket port value is not accepted by the API.",
|
|
462
|
+
likelyCauses: [
|
|
463
|
+
"A malformed environment variable",
|
|
464
|
+
"A number outside the port range"
|
|
465
|
+
],
|
|
466
|
+
suggestions: [
|
|
467
|
+
"Validate and parse the port configuration before creating the connection.",
|
|
468
|
+
"Do not substitute a silent default for a visibly invalid production setting."
|
|
469
|
+
]
|
|
470
|
+
},
|
|
471
|
+
SyntaxError: {
|
|
472
|
+
title: "Invalid JavaScript syntax",
|
|
473
|
+
explanation: "The parser cannot interpret the source or input syntax.",
|
|
474
|
+
likelyCauses: [
|
|
475
|
+
"Malformed JavaScript or JSON",
|
|
476
|
+
"Syntax unsupported by the current runtime"
|
|
477
|
+
],
|
|
478
|
+
suggestions: [
|
|
479
|
+
"Read the first reported location and inspect nearby delimiters and tokens.",
|
|
480
|
+
"Confirm the input format and runtime version before changing unrelated code."
|
|
481
|
+
]
|
|
482
|
+
},
|
|
483
|
+
ReferenceError: {
|
|
484
|
+
title: "Name is not available",
|
|
485
|
+
explanation: "An expression refers to a binding that is not available in its current scope or initialization state.",
|
|
486
|
+
likelyCauses: [
|
|
487
|
+
"A misspelled or out-of-scope variable",
|
|
488
|
+
"Access before initialization"
|
|
489
|
+
],
|
|
490
|
+
suggestions: [
|
|
491
|
+
"Inspect the referenced name and its scope at the reported line.",
|
|
492
|
+
"Check initialization order and add a focused regression test."
|
|
493
|
+
]
|
|
494
|
+
},
|
|
495
|
+
RangeError: {
|
|
496
|
+
title: "Value exceeds a permitted range",
|
|
497
|
+
explanation: "An operation received a value outside its allowed range or exhausted a range-related resource.",
|
|
498
|
+
likelyCauses: [
|
|
499
|
+
"An invalid numeric size or index",
|
|
500
|
+
"Excessive recursion or allocation"
|
|
501
|
+
],
|
|
502
|
+
suggestions: [
|
|
503
|
+
"Read the exact message to distinguish numeric bounds from stack exhaustion.",
|
|
504
|
+
"Inspect boundary values and recursion termination rather than treating every RangeError alike."
|
|
505
|
+
]
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
// src/definitions.js
|
|
510
|
+
var definitions = {
|
|
511
|
+
...extraDefinitions,
|
|
512
|
+
ECONNREFUSED: {
|
|
513
|
+
title: "Connection refused",
|
|
514
|
+
explanation: "The application tried to connect to a service, but nothing accepted the connection.",
|
|
515
|
+
likelyCauses: [
|
|
516
|
+
"The service is not running",
|
|
517
|
+
"The host or port is incorrect",
|
|
518
|
+
"A firewall actively rejected the connection"
|
|
519
|
+
],
|
|
520
|
+
suggestions: [
|
|
521
|
+
"Confirm that the service is running and listening on the configured host and port.",
|
|
522
|
+
"Check connection settings and firewall rules."
|
|
523
|
+
]
|
|
524
|
+
},
|
|
525
|
+
ENOENT: {
|
|
526
|
+
title: "File or directory not found",
|
|
527
|
+
explanation: "The application tried to use a filesystem path that does not exist.",
|
|
528
|
+
likelyCauses: [
|
|
529
|
+
"The path is misspelled",
|
|
530
|
+
"The file was moved or deleted",
|
|
531
|
+
"A relative path is being resolved from an unexpected working directory"
|
|
532
|
+
],
|
|
533
|
+
suggestions: [
|
|
534
|
+
"Check the full path and the current working directory.",
|
|
535
|
+
"Create the required file or directory if it should exist."
|
|
536
|
+
]
|
|
537
|
+
},
|
|
538
|
+
EADDRINUSE: {
|
|
539
|
+
title: "Address already in use",
|
|
540
|
+
explanation: "The application tried to listen on an address and port that another listener already uses.",
|
|
541
|
+
likelyCauses: [
|
|
542
|
+
"Another instance of the application is running",
|
|
543
|
+
"Another service uses the same port"
|
|
544
|
+
],
|
|
545
|
+
suggestions: [
|
|
546
|
+
"Identify the process using the port before stopping it.",
|
|
547
|
+
"Choose a different available port or stop the duplicate instance."
|
|
548
|
+
]
|
|
549
|
+
},
|
|
550
|
+
MODULE_NOT_FOUND: {
|
|
551
|
+
title: "Module not found",
|
|
552
|
+
explanation: "Node.js could not resolve a module requested by the application.",
|
|
553
|
+
likelyCauses: [
|
|
554
|
+
"A dependency is missing",
|
|
555
|
+
"The module path is incorrect",
|
|
556
|
+
"A dependency references a missing module"
|
|
557
|
+
],
|
|
558
|
+
suggestions: [
|
|
559
|
+
"Check the missing module name and the require stack.",
|
|
560
|
+
"Install declared dependencies with npm install and verify local paths."
|
|
561
|
+
]
|
|
562
|
+
},
|
|
563
|
+
ERR_MODULE_NOT_FOUND: {
|
|
564
|
+
title: "ES module not found",
|
|
565
|
+
explanation: "Node.js could not resolve an imported ES module.",
|
|
566
|
+
likelyCauses: [
|
|
567
|
+
"A dependency is missing",
|
|
568
|
+
"The import path or file extension is incorrect"
|
|
569
|
+
],
|
|
570
|
+
suggestions: [
|
|
571
|
+
"Install declared dependencies and verify the import path.",
|
|
572
|
+
"Include the file extension for relative Node.js ES module imports."
|
|
573
|
+
]
|
|
574
|
+
},
|
|
575
|
+
TypeError: {
|
|
576
|
+
title: "Unexpected value type",
|
|
577
|
+
explanation: "An operation received a value it cannot use, such as calling a non-function or reading a property of undefined.",
|
|
578
|
+
likelyCauses: [
|
|
579
|
+
"A value is null or undefined",
|
|
580
|
+
"A value has a different type than expected"
|
|
581
|
+
],
|
|
582
|
+
suggestions: [
|
|
583
|
+
"Inspect the value at the first relevant line in the stack trace.",
|
|
584
|
+
"Check inputs and return values before accessing properties or calling functions."
|
|
585
|
+
]
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
// src/index.js
|
|
590
|
+
var listErrors = () => Object.keys(definitions);
|
|
591
|
+
function translateErrors(errors, options = {}) {
|
|
592
|
+
if (!Array.isArray(errors) || errors.length < 1 || errors.length > 100)
|
|
593
|
+
throw new RangeError("Provide 1\u2013100 errors.");
|
|
594
|
+
return Array.from(errors, (error) => translateError(error, options));
|
|
595
|
+
}
|
|
596
|
+
var duckLines = {
|
|
597
|
+
EACCES: "The file has a guest list. Your process is not on it.",
|
|
598
|
+
EPERM: "The operating system has declined your ambitious proposal.",
|
|
599
|
+
EEXIST: "The target is already here and has not agreed to be replaced.",
|
|
600
|
+
ENOTDIR: "That hallway is actually a cupboard.",
|
|
601
|
+
EISDIR: "You asked for one file and received the whole neighborhood.",
|
|
602
|
+
ENOTEMPTY: "The directory still has roommates.",
|
|
603
|
+
EMFILE: "Your process opened every door and forgot to close them.",
|
|
604
|
+
ENFILE: "The host has run out of chairs for file handles.",
|
|
605
|
+
ENOSPC: "The disk has eaten the final snack.",
|
|
606
|
+
EROFS: "This filesystem is a museum: look, but do not rearrange.",
|
|
607
|
+
EBUSY: "The resource is in another meeting.",
|
|
608
|
+
EXDEV: "The rename has reached the border and needs a different passport.",
|
|
609
|
+
EPIPE: "The audience left before your stream finished the speech.",
|
|
610
|
+
ECONNRESET: "The other end hung up without the usual pleasantries.",
|
|
611
|
+
ETIMEDOUT: "The operation is late and has not brought a believable excuse.",
|
|
612
|
+
ENOTFOUND: "The hostname is not answering roll call.",
|
|
613
|
+
EAI_AGAIN: "DNS requests a brief intermission, not eternal optimism.",
|
|
614
|
+
EADDRNOTAVAIL: "That address does not live on this machine.",
|
|
615
|
+
ECONNABORTED: "The connection left before the conversation was finished.",
|
|
616
|
+
ENETUNREACH: "The packet has no road to the destination.",
|
|
617
|
+
EHOSTUNREACH: "The route exists; the destination is still playing hard to reach.",
|
|
618
|
+
EINVAL: "The argument has failed the entrance interview.",
|
|
619
|
+
ABORT_ERR: "The caller pulled the emergency stop. Ask why before restarting.",
|
|
620
|
+
ERR_INVALID_ARG_TYPE: "The parameter ordered a string and received a surprise guest.",
|
|
621
|
+
ERR_INVALID_ARG_VALUE: "The type is correct. Its life choices are not.",
|
|
622
|
+
ERR_OUT_OF_RANGE: "The number wandered beyond the approved fence.",
|
|
623
|
+
ERR_HTTP_HEADERS_SENT: "The response left the station. You cannot redecorate its headers now.",
|
|
624
|
+
ERR_HTTP_INVALID_STATUS_CODE: "That number is not a useful mood for an HTTP response.",
|
|
625
|
+
ERR_INVALID_URL: "The address has syntax ambitions but no navigable destination.",
|
|
626
|
+
ERR_PACKAGE_PATH_NOT_EXPORTED: "You are trying the package staff entrance.",
|
|
627
|
+
ERR_PACKAGE_IMPORT_NOT_DEFINED: "The alias has not been introduced to this package.",
|
|
628
|
+
ERR_INVALID_PACKAGE_CONFIG: "The package instructions have become abstract art.",
|
|
629
|
+
ERR_UNKNOWN_FILE_EXTENSION: "The loader does not speak this file dialect.",
|
|
630
|
+
ERR_IMPORT_ATTRIBUTE_MISSING: "The import arrived without its required name badge.",
|
|
631
|
+
ERR_STREAM_WRITE_AFTER_END: "The stream said goodbye. Your callback is still talking.",
|
|
632
|
+
ERR_STREAM_DESTROYED: "The stream has retired. Please respect its notice.",
|
|
633
|
+
ERR_SOCKET_BAD_PORT: "The port number did not pass the harbor inspection.",
|
|
634
|
+
SyntaxError: "The parser has found punctuation with questionable intentions.",
|
|
635
|
+
ReferenceError: "That name is not available for comment in this scope.",
|
|
636
|
+
RangeError: "The value or call stack has climbed over the fence.",
|
|
637
|
+
ECONNREFUSED: "Your app knocked. The service has apparently gone for coffee.",
|
|
638
|
+
ENOENT: "The file is playing hide-and-seek. It is currently winning.",
|
|
639
|
+
EADDRINUSE: "Two servers reserved the same chair. Only one gets to sit.",
|
|
640
|
+
MODULE_NOT_FOUND: "The dependency missed roll call. Check its invitation to node_modules.",
|
|
641
|
+
ERR_MODULE_NOT_FOUND: "The module took a wrong turn. Extensions are street signs, not decorations.",
|
|
642
|
+
TypeError: "JavaScript received a surprise guest and forgot how to behave."
|
|
643
|
+
};
|
|
644
|
+
function translateError(error, options = {}) {
|
|
645
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
646
|
+
throw new TypeError("Options must be an object.");
|
|
647
|
+
}
|
|
648
|
+
const mode = options.mode ?? "plain";
|
|
649
|
+
if (!["plain", "rubber-duck"].includes(mode))
|
|
650
|
+
throw new RangeError("Supported modes: plain, rubber-duck.");
|
|
651
|
+
let code;
|
|
652
|
+
let name;
|
|
653
|
+
let message;
|
|
654
|
+
if (typeof error === "string") {
|
|
655
|
+
message = error.trim();
|
|
656
|
+
} else if (error && typeof error === "object" && !Array.isArray(error)) {
|
|
657
|
+
for (const field of ["code", "name", "message"]) {
|
|
658
|
+
if (error[field] !== void 0 && typeof error[field] !== "string") {
|
|
659
|
+
throw new TypeError(`Error ${field} must be a string.`);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
code = error.code?.trim();
|
|
663
|
+
name = error.name?.trim();
|
|
664
|
+
message = error.message?.trim();
|
|
665
|
+
} else {
|
|
666
|
+
throw new TypeError(
|
|
667
|
+
"Provide a nonempty error string or error-like object."
|
|
668
|
+
);
|
|
669
|
+
}
|
|
670
|
+
if (!code && !name && !message)
|
|
671
|
+
throw new TypeError(
|
|
672
|
+
"Provide a nonempty error string or error-like object."
|
|
673
|
+
);
|
|
674
|
+
const matched = code || (Object.hasOwn(definitions, name ?? "") ? name : void 0) || Object.keys(definitions).find(
|
|
675
|
+
(key) => new RegExp(`\\b${key}\\b`).test(message ?? "")
|
|
676
|
+
);
|
|
677
|
+
const definition = Object.hasOwn(definitions, matched ?? "") ? definitions[matched] : void 0;
|
|
678
|
+
const fallback = {
|
|
679
|
+
title: "Unrecognized error",
|
|
680
|
+
explanation: "No built-in translation matches this error yet.",
|
|
681
|
+
likelyCauses: [],
|
|
682
|
+
suggestions: [
|
|
683
|
+
"Read the original error and inspect the first relevant line in its stack trace.",
|
|
684
|
+
"Check the documentation for the component that reported the error."
|
|
685
|
+
]
|
|
686
|
+
};
|
|
687
|
+
const result = definition ?? fallback;
|
|
688
|
+
return {
|
|
689
|
+
code: matched ?? "UNKNOWN",
|
|
690
|
+
...result,
|
|
691
|
+
explanation: mode === "rubber-duck" ? `${result.explanation} ${Object.hasOwn(duckLines, matched ?? "") ? duckLines[matched] : "The duck recommends investigating before blaming the compiler."}` : result.explanation,
|
|
692
|
+
likelyCauses: [...result.likelyCauses],
|
|
693
|
+
suggestions: [...result.suggestions],
|
|
694
|
+
mode
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
function renderTranslation(result) {
|
|
698
|
+
if (!result || typeof result.title !== "string" || typeof result.explanation !== "string" || !Array.isArray(result.likelyCauses) || !Array.isArray(result.suggestions) || ![...result.likelyCauses, ...result.suggestions].every(
|
|
699
|
+
(item) => typeof item === "string"
|
|
700
|
+
)) {
|
|
701
|
+
throw new TypeError("Provide a structured translation result.");
|
|
702
|
+
}
|
|
703
|
+
return [
|
|
704
|
+
result.title,
|
|
705
|
+
`What happened:
|
|
706
|
+
${result.explanation}`,
|
|
707
|
+
...result.likelyCauses.length ? [
|
|
708
|
+
`Likely causes:
|
|
709
|
+
${result.likelyCauses.map((item) => `- ${item}`).join("\n")}`
|
|
710
|
+
] : [],
|
|
711
|
+
...result.suggestions.length ? [`Try:
|
|
712
|
+
${result.suggestions.map((item) => `- ${item}`).join("\n")}`] : []
|
|
713
|
+
].join("\n\n");
|
|
714
|
+
}
|
|
715
|
+
function errorCatalog(options = {}) {
|
|
716
|
+
return listErrors().map((code) => translateError({ code }, options));
|
|
717
|
+
}
|
|
718
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
719
|
+
0 && (module.exports = {
|
|
720
|
+
errorCatalog,
|
|
721
|
+
listErrors,
|
|
722
|
+
renderTranslation,
|
|
723
|
+
translateError,
|
|
724
|
+
translateErrors
|
|
725
|
+
});
|