1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
type PosixErrNo = MapKeysType<ReturnType<typeof getPosixSystemErrorMap>>;
type Win32ErrNo = MapKeysType<ReturnType<typeof getWin32SystemErrorMap>>;
export function getCallSites(sliceOff = 1) {
const originalPST = Error.prepareStackTrace;
Error.prepareStackTrace = (error, stack) => stack;
const { stack } = new Error();
if (stack?.constructor.name !== 'Array') throw new Error('Failed to acquire structured JS stack trace');
Error.prepareStackTrace = originalPST;
return (stack as unknown as NodeJS.CallSite[]).slice(sliceOff);
}
export function getPosixSystemErrorMap() {
return new Map([
[ -7, [ 'E2BIG', 'argument list too long' ] ],
[ -13, [ 'EACCES', 'permission denied' ] ],
[ -98, [ 'EADDRINUSE', 'address already in use' ] ],
[ -99, [ 'EADDRNOTAVAIL', 'address not available' ] ],
[ -97, [ 'EAFNOSUPPORT', 'address family not supported' ] ],
[ -11, [ 'EAGAIN', 'resource temporarily unavailable' ] ],
[ -3000, [ 'EAI_ADDRFAMILY', 'address family not supported' ] ],
[ -3001, [ 'EAI_AGAIN', 'temporary failure' ] ],
[ -3002, [ 'EAI_BADFLAGS', 'bad ai_flags value' ] ],
[ -3013, [ 'EAI_BADHINTS', 'invalid value for hints' ] ],
[ -3003, [ 'EAI_CANCELED', 'request canceled' ] ],
[ -3004, [ 'EAI_FAIL', 'permanent failure' ] ],
[ -3005, [ 'EAI_FAMILY', 'ai_family not supported' ] ],
[ -3006, [ 'EAI_MEMORY', 'out of memory' ] ],
[ -3007, [ 'EAI_NODATA', 'no address' ] ],
[ -3008, [ 'EAI_NONAME', 'unknown node or service' ] ],
[ -3009, [ 'EAI_OVERFLOW', 'argument buffer overflow' ] ],
[ -3014, [ 'EAI_PROTOCOL', 'resolved protocol is unknown' ] ],
[ -3010, [ 'EAI_SERVICE', 'service not available for socket type' ] ],
[ -3011, [ 'EAI_SOCKTYPE', 'socket type not supported' ] ],
[ -114, [ 'EALREADY', 'connection already in progress' ] ],
[ -9, [ 'EBADF', 'bad file descriptor' ] ],
[ -16, [ 'EBUSY', 'resource busy or locked' ] ],
[ -125, [ 'ECANCELED', 'operation canceled' ] ],
[ -4080, [ 'ECHARSET', 'invalid Unicode character' ] ],
[ -103, [ 'ECONNABORTED', 'software caused connection abort' ] ],
[ -111, [ 'ECONNREFUSED', 'connection refused' ] ],
[ -104, [ 'ECONNRESET', 'connection reset by peer' ] ],
[ -89, [ 'EDESTADDRREQ', 'destination address required' ] ],
[ -17, [ 'EEXIST', 'file already exists' ] ],
[ -14, [ 'EFAULT', 'bad address in system call argument' ] ],
[ -27, [ 'EFBIG', 'file too large' ] ],
[ -113, [ 'EHOSTUNREACH', 'host is unreachable' ] ],
[ -4, [ 'EINTR', 'interrupted system call' ] ],
[ -22, [ 'EINVAL', 'invalid argument' ] ],
[ -5, [ 'EIO', 'i/o error' ] ],
[ -106, [ 'EISCONN', 'socket is already connected' ] ],
[ -21, [ 'EISDIR', 'illegal operation on a directory' ] ],
[ -40, [ 'ELOOP', 'too many symbolic links encountered' ] ],
[ -24, [ 'EMFILE', 'too many open files' ] ],
[ -90, [ 'EMSGSIZE', 'message too long' ] ],
[ -36, [ 'ENAMETOOLONG', 'name too long' ] ],
[ -100, [ 'ENETDOWN', 'network is down' ] ],
[ -101, [ 'ENETUNREACH', 'network is unreachable' ] ],
[ -23, [ 'ENFILE', 'file table overflow' ] ],
[ -105, [ 'ENOBUFS', 'no buffer space available' ] ],
[ -19, [ 'ENODEV', 'no such device' ] ],
[ -2, [ 'ENOENT', 'no such file or directory' ] ],
[ -12, [ 'ENOMEM', 'not enough memory' ] ],
[ -64, [ 'ENONET', 'machine is not on the network' ] ],
[ -92, [ 'ENOPROTOOPT', 'protocol not available' ] ],
[ -28, [ 'ENOSPC', 'no space left on device' ] ],
[ -38, [ 'ENOSYS', 'function not implemented' ] ],
[ -107, [ 'ENOTCONN', 'socket is not connected' ] ],
[ -20, [ 'ENOTDIR', 'not a directory' ] ],
[ -39, [ 'ENOTEMPTY', 'directory not empty' ] ],
[ -88, [ 'ENOTSOCK', 'socket operation on non-socket' ] ],
[ -95, [ 'ENOTSUP', 'operation not supported on socket' ] ],
[ -75, [ 'EOVERFLOW', 'value too large for defined data type' ] ],
[ -1, [ 'EPERM', 'operation not permitted' ] ],
[ -32, [ 'EPIPE', 'broken pipe' ] ],
[ -71, [ 'EPROTO', 'protocol error' ] ],
[ -93, [ 'EPROTONOSUPPORT', 'protocol not supported' ] ],
[ -91, [ 'EPROTOTYPE', 'protocol wrong type for socket' ] ],
[ -34, [ 'ERANGE', 'result too large' ] ],
[ -30, [ 'EROFS', 'read-only file system' ] ],
[ -108, [ 'ESHUTDOWN', 'cannot send after transport endpoint shutdown' ] ],
[ -29, [ 'ESPIPE', 'invalid seek' ] ],
[ -3, [ 'ESRCH', 'no such process' ] ],
[ -110, [ 'ETIMEDOUT', 'connection timed out' ] ],
[ -26, [ 'ETXTBSY', 'text file is busy' ] ],
[ -18, [ 'EXDEV', 'cross-device link not permitted' ] ],
[ -4094, [ 'UNKNOWN', 'unknown error' ] ],
[ -4095, [ 'EOF', 'end of file' ] ],
[ -6, [ 'ENXIO', 'no such device or address' ] ],
[ -31, [ 'EMLINK', 'too many links' ] ],
[ -112, [ 'EHOSTDOWN', 'host is down' ] ],
[ -121, [ 'EREMOTEIO', 'remote I/O error' ] ],
[ -25, [ 'ENOTTY', 'inappropriate ioctl for device' ] ],
[ -4028, [ 'EFTYPE', 'inappropriate file type or format' ] ],
[ -84, [ 'EILSEQ', 'illegal byte sequence' ] ],
[ -94, [ 'ESOCKTNOSUPPORT', 'socket type not supported' ] ]
] as const);
}
export function getWin32SystemErrorMap() {
return new Map([
[ -4093, [ 'E2BIG', 'argument list too long' ] ],
[ -4092, [ 'EACCES', 'permission denied' ] ],
[ -4091, [ 'EADDRINUSE', 'address already in use' ] ],
[ -4090, [ 'EADDRNOTAVAIL', 'address not available' ] ],
[ -4089, [ 'EAFNOSUPPORT', 'address family not supported' ] ],
[ -4088, [ 'EAGAIN', 'resource temporarily unavailable' ] ],
[ -3000, [ 'EAI_ADDRFAMILY', 'address family not supported' ] ],
[ -3001, [ 'EAI_AGAIN', 'temporary failure' ] ],
[ -3002, [ 'EAI_BADFLAGS', 'bad ai_flags value' ] ],
[ -3013, [ 'EAI_BADHINTS', 'invalid value for hints' ] ],
[ -3003, [ 'EAI_CANCELED', 'request canceled' ] ],
[ -3004, [ 'EAI_FAIL', 'permanent failure' ] ],
[ -3005, [ 'EAI_FAMILY', 'ai_family not supported' ] ],
[ -3006, [ 'EAI_MEMORY', 'out of memory' ] ],
[ -3007, [ 'EAI_NODATA', 'no address' ] ],
[ -3008, [ 'EAI_NONAME', 'unknown node or service' ] ],
[ -3009, [ 'EAI_OVERFLOW', 'argument buffer overflow' ] ],
[ -3014, [ 'EAI_PROTOCOL', 'resolved protocol is unknown' ] ],
[ -3010, [ 'EAI_SERVICE', 'service not available for socket type' ] ],
[ -3011, [ 'EAI_SOCKTYPE', 'socket type not supported' ] ],
[ -4084, [ 'EALREADY', 'connection already in progress' ] ],
[ -4083, [ 'EBADF', 'bad file descriptor' ] ],
[ -4082, [ 'EBUSY', 'resource busy or locked' ] ],
[ -4081, [ 'ECANCELED', 'operation canceled' ] ],
[ -4080, [ 'ECHARSET', 'invalid Unicode character' ] ],
[ -4079, [ 'ECONNABORTED', 'software caused connection abort' ] ],
[ -4078, [ 'ECONNREFUSED', 'connection refused' ] ],
[ -4077, [ 'ECONNRESET', 'connection reset by peer' ] ],
[ -4076, [ 'EDESTADDRREQ', 'destination address required' ] ],
[ -4075, [ 'EEXIST', 'file already exists' ] ],
[ -4074, [ 'EFAULT', 'bad address in system call argument' ] ],
[ -4036, [ 'EFBIG', 'file too large' ] ],
[ -4073, [ 'EHOSTUNREACH', 'host is unreachable' ] ],
[ -4072, [ 'EINTR', 'interrupted system call' ] ],
[ -4071, [ 'EINVAL', 'invalid argument' ] ],
[ -4070, [ 'EIO', 'i/o error' ] ],
[ -4069, [ 'EISCONN', 'socket is already connected' ] ],
[ -4068, [ 'EISDIR', 'illegal operation on a directory' ] ],
[ -4067, [ 'ELOOP', 'too many symbolic links encountered' ] ],
[ -4066, [ 'EMFILE', 'too many open files' ] ],
[ -4065, [ 'EMSGSIZE', 'message too long' ] ],
[ -4064, [ 'ENAMETOOLONG', 'name too long' ] ],
[ -4063, [ 'ENETDOWN', 'network is down' ] ],
[ -4062, [ 'ENETUNREACH', 'network is unreachable' ] ],
[ -4061, [ 'ENFILE', 'file table overflow' ] ],
[ -4060, [ 'ENOBUFS', 'no buffer space available' ] ],
[ -4059, [ 'ENODEV', 'no such device' ] ],
[ -4058, [ 'ENOENT', 'no such file or directory' ] ],
[ -4057, [ 'ENOMEM', 'not enough memory' ] ],
[ -4056, [ 'ENONET', 'machine is not on the network' ] ],
[ -4035, [ 'ENOPROTOOPT', 'protocol not available' ] ],
[ -4055, [ 'ENOSPC', 'no space left on device' ] ],
[ -4054, [ 'ENOSYS', 'function not implemented' ] ],
[ -4053, [ 'ENOTCONN', 'socket is not connected' ] ],
[ -4052, [ 'ENOTDIR', 'not a directory' ] ],
[ -4051, [ 'ENOTEMPTY', 'directory not empty' ] ],
[ -4050, [ 'ENOTSOCK', 'socket operation on non-socket' ] ],
[ -4049, [ 'ENOTSUP', 'operation not supported on socket' ] ],
[ -4026, [ 'EOVERFLOW', 'value too large for defined data type' ] ],
[ -4048, [ 'EPERM', 'operation not permitted' ] ],
[ -4047, [ 'EPIPE', 'broken pipe' ] ],
[ -4046, [ 'EPROTO', 'protocol error' ] ],
[ -4045, [ 'EPROTONOSUPPORT', 'protocol not supported' ] ],
[ -4044, [ 'EPROTOTYPE', 'protocol wrong type for socket' ] ],
[ -4034, [ 'ERANGE', 'result too large' ] ],
[ -4043, [ 'EROFS', 'read-only file system' ] ],
[ -4042, [ 'ESHUTDOWN', 'cannot send after transport endpoint shutdown' ] ],
[ -4041, [ 'ESPIPE', 'invalid seek' ] ],
[ -4040, [ 'ESRCH', 'no such process' ] ],
[ -4039, [ 'ETIMEDOUT', 'connection timed out' ] ],
[ -4038, [ 'ETXTBSY', 'text file is busy' ] ],
[ -4037, [ 'EXDEV', 'cross-device link not permitted' ] ],
[ -4094, [ 'UNKNOWN', 'unknown error' ] ],
[ -4095, [ 'EOF', 'end of file' ] ],
[ -4033, [ 'ENXIO', 'no such device or address' ] ],
[ -4032, [ 'EMLINK', 'too many links' ] ],
[ -4031, [ 'EHOSTDOWN', 'host is down' ] ],
[ -4030, [ 'EREMOTEIO', 'remote I/O error' ] ],
[ -4029, [ 'ENOTTY', 'inappropriate ioctl for device' ] ],
[ -4028, [ 'EFTYPE', 'inappropriate file type or format' ] ],
[ -4027, [ 'EILSEQ', 'illegal byte sequence' ] ],
[ -4025, [ 'ESOCKTNOSUPPORT', 'socket type not supported' ] ]
] as const);
}
export function getPosixToWin32SystemErrorMap() {
const posixEntries = [...getPosixSystemErrorMap().entries()];
const win32Entries = [...getWin32SystemErrorMap().entries()];
const map: Map<PosixErrNo, Win32ErrNo> = new Map();
posixEntries.forEach(([code, val]) => {
const found = win32Entries.find(([_, v]) => v[0] === val[0]);
if (!found) console.error(val[0]);
else map.set(code, found[0]);
});
return map;
}
export function getPlatformSystemErrorFromPosix(posixErrNo: PosixErrNo) {
if (process.platform === 'win32') {
const win32errno = getPosixToWin32SystemErrorMap().get(posixErrNo)!;
return getWin32SystemErrorMap().get(win32errno);
} else {
return getPosixSystemErrorMap().get(posixErrNo);
}
}
export class SystemError extends Error {
constructor(errno: PosixErrNo, syscall?: string, errpath?: string) {
const [errname, errmsg] = getPlatformSystemErrorFromPosix(errno) ?? ['SystemError', 'Unknown system error'];
super(errmsg);
this.name = errname;
this.code = errname;
this.errno = errno;
if (syscall) this.syscall = syscall;
if (errpath) this.path = errpath;
}
errno?: number | undefined;
code?: string | undefined;
path?: string | undefined;
syscall?: string | undefined;
}
export class NotImplementedError extends Error {
constructor(thing: string, func: AnyCallable = NotImplementedError, overrideMsg: boolean = false) {
super(overrideMsg ? thing : `A polyfill for ${thing} is not yet implemented by bun-polyfills.`);
this.name = 'NotImplementedError';
Error.captureStackTrace(this, func);
}
}
|