@starpak/error 0.0.0-stage → 0.1.4
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 +22 -0
- package/lib/codes.d.ts +90 -0
- package/lib/codes.d.ts.map +1 -0
- package/lib/codes.js +108 -0
- package/lib/codes.js.map +1 -0
- package/lib/definitions.d.ts +31 -0
- package/lib/definitions.d.ts.map +1 -0
- package/lib/definitions.js +114 -0
- package/lib/definitions.js.map +1 -0
- package/lib/error.d.ts +61 -0
- package/lib/error.d.ts.map +1 -0
- package/lib/error.js +89 -0
- package/lib/error.js.map +1 -0
- package/lib/format.d.ts +18 -0
- package/lib/format.d.ts.map +1 -0
- package/lib/format.js +164 -0
- package/lib/format.js.map +1 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +29 -0
- package/lib/index.js.map +1 -0
- package/lib/native.d.ts +20 -0
- package/lib/native.d.ts.map +1 -0
- package/lib/native.js +97 -0
- package/lib/native.js.map +1 -0
- package/package.json +11 -3
- package/src/codes.ts +115 -0
- package/src/definitions.ts +232 -0
- package/src/error.ts +123 -0
- package/src/format.ts +183 -0
- package/src/index.ts +20 -0
- package/src/native.ts +108 -0
- package/README.md +0 -3
package/src/native.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spak Error - native error mapping
|
|
3
|
+
*
|
|
4
|
+
* Turns `errno` codes and well-known crash messages into Spak errors while
|
|
5
|
+
* keeping the original error as `cause`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { CODES } from './codes'
|
|
9
|
+
import { SpakError, isSpakError } from './error'
|
|
10
|
+
|
|
11
|
+
/** POSIX/Node errno → Spak code. */
|
|
12
|
+
export const ERRNO_MAP: Record<string, string> = {
|
|
13
|
+
ENOENT: CODES.FS_NOT_FOUND,
|
|
14
|
+
ENOTDIR: CODES.FS_NOT_FOUND,
|
|
15
|
+
EACCES: CODES.FS_DENIED_BY_OS,
|
|
16
|
+
EPERM: CODES.FS_OPERATION_NOT_PERMITTED,
|
|
17
|
+
ENOSPC: CODES.FS_NO_SPACE,
|
|
18
|
+
EMFILE: CODES.FS_TOO_MANY_OPEN_FILES,
|
|
19
|
+
ENFILE: CODES.FS_TOO_MANY_OPEN_FILES,
|
|
20
|
+
EISDIR: CODES.FS_IS_DIRECTORY,
|
|
21
|
+
EROFS: CODES.FS_DENIED_BY_OS,
|
|
22
|
+
EBADF: CODES.HANDLE_REVOKED,
|
|
23
|
+
|
|
24
|
+
EADDRINUSE: CODES.PORT_IN_USE,
|
|
25
|
+
EADDRNOTAVAIL: CODES.LISTEN_FAILED,
|
|
26
|
+
EACCES_LISTEN: CODES.LISTEN_FAILED,
|
|
27
|
+
|
|
28
|
+
ECONNREFUSED: CODES.NET_CONNECTION_REFUSED,
|
|
29
|
+
ECONNRESET: CODES.NET_CONNECTION_RESET,
|
|
30
|
+
ECONNABORTED: CODES.NET_CONNECTION_RESET,
|
|
31
|
+
EPIPE: CODES.NET_CONNECTION_RESET,
|
|
32
|
+
ETIMEDOUT: CODES.NET_TIMEOUT,
|
|
33
|
+
ESOCKETTIMEDOUT: CODES.NET_TIMEOUT,
|
|
34
|
+
ENOTFOUND: CODES.NET_DNS,
|
|
35
|
+
EAI_AGAIN: CODES.NET_DNS,
|
|
36
|
+
|
|
37
|
+
ERR_TLS_CERT_ALTNAME_INVALID: CODES.NET_TLS,
|
|
38
|
+
ERR_SSL_WRONG_VERSION_NUMBER: CODES.NET_TLS,
|
|
39
|
+
DEPTH_ZERO_SELF_SIGNED_CERT: CODES.NET_TLS,
|
|
40
|
+
UNABLE_TO_VERIFY_LEAF_SIGNATURE: CODES.NET_TLS,
|
|
41
|
+
SELF_SIGNED_CERT_IN_CHAIN: CODES.NET_TLS,
|
|
42
|
+
|
|
43
|
+
MODULE_NOT_FOUND: CODES.MODULE_NOT_FOUND,
|
|
44
|
+
ERR_MODULE_NOT_FOUND: CODES.MODULE_NOT_FOUND,
|
|
45
|
+
ERR_REQUIRE_ESM: CODES.MODULE_NOT_FOUND,
|
|
46
|
+
ERR_PACKAGE_PATH_NOT_EXPORTED: CODES.MODULE_NOT_FOUND,
|
|
47
|
+
ERR_INVALID_ARG_TYPE: CODES.BUILD_FAILED,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Message patterns for failures that have no errno (crashes, engine errors). */
|
|
51
|
+
const MESSAGE_MAP: Array<{ pattern: RegExp, code: string }> = [
|
|
52
|
+
{ pattern: /JavaScript heap out of memory/i, code: CODES.OUT_OF_MEMORY },
|
|
53
|
+
{ pattern: /Maximum call stack size exceeded/i, code: CODES.STACK_OVERFLOW },
|
|
54
|
+
{ pattern: /Segmentation fault|core dumped|double free|invalid pointer|bus error/i, code: CODES.NATIVE_CRASH },
|
|
55
|
+
{ pattern: /Unexpected token .* in JSON|is not valid JSON|JSON at position/i, code: CODES.PAK_MANIFEST_INVALID },
|
|
56
|
+
{ pattern: /\.l2s\.|FUSE|rename .*ENOENT/i, code: CODES.FS_RENAME_UNSUPPORTED },
|
|
57
|
+
{ pattern: /socket hang up/i, code: CODES.NET_CONNECTION_RESET },
|
|
58
|
+
{ pattern: /self-signed certificate|certificate has expired|unable to verify/i, code: CODES.NET_TLS },
|
|
59
|
+
{ pattern: /basic auth|proxy authentication/i, code: CODES.NET_PROXY_AUTH },
|
|
60
|
+
{ pattern: /Cannot find module/i, code: CODES.MODULE_NOT_FOUND },
|
|
61
|
+
{ pattern: /EACCES.*listen|permission denied.*:?\d{2,5}/i, code: CODES.LISTEN_FAILED },
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
export interface NativeOptions {
|
|
65
|
+
where?: string
|
|
66
|
+
context?: Record<string, unknown>
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Normalise any thrown value into a `SpakError`.
|
|
71
|
+
* Unknown shapes still produce an error (SPAK-9999) with the original cause.
|
|
72
|
+
*/
|
|
73
|
+
export function fromNative(error: unknown, options: NativeOptions = {}): SpakError {
|
|
74
|
+
if (isSpakError(error)) return error
|
|
75
|
+
|
|
76
|
+
const cause = error instanceof Error ? error : new Error(String(error))
|
|
77
|
+
const errno = typeof (error as { code?: unknown })?.code === 'string'
|
|
78
|
+
? String((error as { code?: string }).code)
|
|
79
|
+
: undefined
|
|
80
|
+
const message = cause.message ?? ''
|
|
81
|
+
const context: Record<string, unknown> = { ...options.context }
|
|
82
|
+
if (errno) context.errno = errno
|
|
83
|
+
|
|
84
|
+
if (errno) {
|
|
85
|
+
const direct = ERRNO_MAP[errno]
|
|
86
|
+
if (direct) {
|
|
87
|
+
// Listen failures share EACCES with file access; the syscall tells them apart.
|
|
88
|
+
const syscall = String((error as { syscall?: unknown })?.syscall ?? '')
|
|
89
|
+
if (errno === 'EACCES' && syscall === 'listen') {
|
|
90
|
+
return new SpakError(CODES.LISTEN_FAILED, { cause, message, where: options.where, context })
|
|
91
|
+
}
|
|
92
|
+
if (errno === 'ENOENT' && /\.l2s\.|tmp_obj_|\.git\/objects/.test(message)) {
|
|
93
|
+
return new SpakError(CODES.FS_RENAME_UNSUPPORTED, { cause, message, where: options.where, context })
|
|
94
|
+
}
|
|
95
|
+
return new SpakError(direct, { cause, message, where: options.where, context })
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
for (const entry of MESSAGE_MAP) {
|
|
100
|
+
if (entry.pattern.test(message)) {
|
|
101
|
+
return new SpakError(entry.code, { cause, message, where: options.where, context })
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return new SpakError(CODES.UNKNOWN, { cause, message, where: options.where, context })
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export { ERRNO_MAP as ERRNO_TO_SPAK }
|
package/README.md
DELETED