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
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use anyhow::Error;
pub fn get_error_code(err: &Error) -> Option<&'static str> {
err
.downcast_ref::<std::io::Error>()
.or_else(|| err.chain().find_map(|e| e.downcast_ref::<std::io::Error>()))
.map(|e| match e.raw_os_error() {
Some(code) => get_os_error_code(code),
None => get_io_error_code(e),
})
.and_then(|code| match code.is_empty() {
true => None,
false => Some(code),
})
}
fn get_io_error_code(err: &std::io::Error) -> &'static str {
// not exhaustive but simple and possibly sufficient once `io_error_more` is stabilized (https://github.com/rust-lang/rust/issues/86442)
// inversion of https://github.com/rust-lang/rust/blob/dca3f1b786efd27be3b325ed1e01e247aa589c3b/library/std/src/sys/unix/mod.rs#L138-L185
// TODO(@AaronO): revisit as `io_error_more` lands in rust stable
use std::io::ErrorKind;
match err.kind() {
// ErrorKind::ArgumentListTooLong => "E2BIG",
ErrorKind::AddrInUse => "EADDRINUSE",
ErrorKind::AddrNotAvailable => "EADDRNOTAVAIL",
// ErrorKind::ResourceBusy => "EBUSY",
ErrorKind::ConnectionAborted => "ECONNABORTED",
ErrorKind::ConnectionRefused => "ECONNREFUSED",
ErrorKind::ConnectionReset => "ECONNRESET",
// ErrorKind::Deadlock => "EDEADLK",
// ErrorKind::FilesystemQuotaExceeded => "EDQUOT",
ErrorKind::AlreadyExists => "EEXIST",
// ErrorKind::FileTooLarge => "EFBIG",
// ErrorKind::HostUnreachable => "EHOSTUNREACH",
ErrorKind::Interrupted => "EINTR",
ErrorKind::InvalidInput => "EINVAL",
// ErrorKind::IsADirectory => "EISDIR",
// ErrorKind::FilesystemLoop => "ELOOP",
ErrorKind::NotFound => "ENOENT",
ErrorKind::OutOfMemory => "ENOMEM",
// ErrorKind::StorageFull => "ENOSPC",
ErrorKind::Unsupported => "ENOSYS",
// ErrorKind::TooManyLinks => "EMLINK",
// ErrorKind::FilenameTooLong => "ENAMETOOLONG",
// ErrorKind::NetworkDown => "ENETDOWN",
// ErrorKind::NetworkUnreachable => "ENETUNREACH",
ErrorKind::NotConnected => "ENOTCONN",
// ErrorKind::NotADirectory => "ENOTDIR",
// ErrorKind::DirectoryNotEmpty => "ENOTEMPTY",
ErrorKind::BrokenPipe => "EPIPE",
// ErrorKind::ReadOnlyFilesystem => "EROFS",
// ErrorKind::NotSeekable => "ESPIPE",
// ErrorKind::StaleNetworkFileHandle => "ESTALE",
ErrorKind::TimedOut => "ETIMEDOUT",
// ErrorKind::ExecutableFileBusy => "ETXTBSY",
// ErrorKind::CrossesDevices => "EXDEV",
ErrorKind::PermissionDenied => "EACCES", // NOTE: Collides with EPERM ...
ErrorKind::WouldBlock => "EWOULDBLOCK", // NOTE: Collides with EAGAIN ...
_ => "",
}
}
/// Maps OS errno codes to string names
/// derived from libuv: https://github.com/libuv/libuv/blob/26b2e5dbb6301756644d6e4cf6ca9c49c00513d3/include/uv/errno.h
/// generated with tools/codegen_error_codes.js
#[cfg(unix)]
fn get_os_error_code(errno: i32) -> &'static str {
match errno {
libc::E2BIG => "E2BIG",
libc::EACCES => "EACCES",
libc::EADDRINUSE => "EADDRINUSE",
libc::EADDRNOTAVAIL => "EADDRNOTAVAIL",
libc::EAFNOSUPPORT => "EAFNOSUPPORT",
libc::EAGAIN => "EAGAIN",
libc::EALREADY => "EALREADY",
libc::EBADF => "EBADF",
libc::EBUSY => "EBUSY",
libc::ECANCELED => "ECANCELED",
libc::ECONNABORTED => "ECONNABORTED",
libc::ECONNREFUSED => "ECONNREFUSED",
libc::ECONNRESET => "ECONNRESET",
libc::EEXIST => "EEXIST",
libc::EFAULT => "EFAULT",
libc::EHOSTUNREACH => "EHOSTUNREACH",
libc::EINVAL => "EINVAL",
libc::EIO => "EIO",
libc::EISCONN => "EISCONN",
libc::EISDIR => "EISDIR",
libc::ELOOP => "ELOOP",
libc::EMFILE => "EMFILE",
libc::EMSGSIZE => "EMSGSIZE",
libc::ENAMETOOLONG => "ENAMETOOLONG",
libc::ENETUNREACH => "ENETUNREACH",
libc::ENOBUFS => "ENOBUFS",
libc::ENOENT => "ENOENT",
libc::ENOMEM => "ENOMEM",
libc::ENOSPC => "ENOSPC",
libc::ENOTCONN => "ENOTCONN",
libc::ENOTDIR => "ENOTDIR",
libc::ENOTEMPTY => "ENOTEMPTY",
libc::ENOTSOCK => "ENOTSOCK",
libc::ENOTSUP => "ENOTSUP",
libc::EPERM => "EPERM",
libc::EPIPE => "EPIPE",
libc::EPROTONOSUPPORT => "EPROTONOSUPPORT",
libc::EROFS => "EROFS",
libc::ETIMEDOUT => "ETIMEDOUT",
libc::EXDEV => "EXDEV",
libc::ESOCKTNOSUPPORT => "ESOCKTNOSUPPORT",
_ => "",
}
}
#[cfg(windows)]
fn get_os_error_code(errno: i32) -> &'static str {
match errno {
998 => "EACCES", // ERROR_NOACCESS
10013 => "EACCES", // WSAEACCES
1920 => "EACCES", // ERROR_CANT_ACCESS_FILE
1227 => "EADDRINUSE", // ERROR_ADDRESS_ALREADY_ASSOCIATED
10048 => "EADDRINUSE", // WSAEADDRINUSE
10049 => "EADDRNOTAVAIL", // WSAEADDRNOTAVAIL
10047 => "EAFNOSUPPORT", // WSAEAFNOSUPPORT
10035 => "EAGAIN", // WSAEWOULDBLOCK
10037 => "EALREADY", // WSAEALREADY
1004 => "EBADF", // ERROR_INVALID_FLAGS
6 => "EBADF", // ERROR_INVALID_HANDLE
33 => "EBUSY", // ERROR_LOCK_VIOLATION
231 => "EBUSY", // ERROR_PIPE_BUSY
32 => "EBUSY", // ERROR_SHARING_VIOLATION
995 => "ECANCELED", // ERROR_OPERATION_ABORTED
10004 => "ECANCELED", // WSAEINTR
1236 => "ECONNABORTED", // ERROR_CONNECTION_ABORTED
10053 => "ECONNABORTED", // WSAECONNABORTED
1225 => "ECONNREFUSED", // ERROR_CONNECTION_REFUSED
10061 => "ECONNREFUSED", // WSAECONNREFUSED
64 => "ECONNRESET", // ERROR_NETNAME_DELETED
10054 => "ECONNRESET", // WSAECONNRESET
183 => "EEXIST", // ERROR_ALREADY_EXISTS
80 => "EEXIST", // ERROR_FILE_EXISTS
111 => "EFAULT", // ERROR_BUFFER_OVERFLOW
10014 => "EFAULT", // WSAEFAULT
1232 => "EHOSTUNREACH", // ERROR_HOST_UNREACHABLE
10065 => "EHOSTUNREACH", // WSAEHOSTUNREACH
122 => "EINVAL", // ERROR_INSUFFICIENT_BUFFER
13 => "EINVAL", // ERROR_INVALID_DATA
87 => "EINVAL", // ERROR_INVALID_PARAMETER
1464 => "EINVAL", // ERROR_SYMLINK_NOT_SUPPORTED
10022 => "EINVAL", // WSAEINVAL
10046 => "EINVAL", // WSAEPFNOSUPPORT
1102 => "EIO", // ERROR_BEGINNING_OF_MEDIA
1111 => "EIO", // ERROR_BUS_RESET
23 => "EIO", // ERROR_CRC
1166 => "EIO", // ERROR_DEVICE_DOOR_OPEN
1165 => "EIO", // ERROR_DEVICE_REQUIRES_CLEANING
1393 => "EIO", // ERROR_DISK_CORRUPT
1129 => "EIO", // ERROR_EOM_OVERFLOW
1101 => "EIO", // ERROR_FILEMARK_DETECTED
31 => "EIO", // ERROR_GEN_FAILURE
1106 => "EIO", // ERROR_INVALID_BLOCK_LENGTH
1117 => "EIO", // ERROR_IO_DEVICE
1104 => "EIO", // ERROR_NO_DATA_DETECTED
205 => "EIO", // ERROR_NO_SIGNAL_SENT
110 => "EIO", // ERROR_OPEN_FAILED
1103 => "EIO", // ERROR_SETMARK_DETECTED
156 => "EIO", // ERROR_SIGNAL_REFUSED
10056 => "EISCONN", // WSAEISCONN
1921 => "ELOOP", // ERROR_CANT_RESOLVE_FILENAME
4 => "EMFILE", // ERROR_TOO_MANY_OPEN_FILES
10024 => "EMFILE", // WSAEMFILE
10040 => "EMSGSIZE", // WSAEMSGSIZE
206 => "ENAMETOOLONG", // ERROR_FILENAME_EXCED_RANGE
1231 => "ENETUNREACH", // ERROR_NETWORK_UNREACHABLE
10051 => "ENETUNREACH", // WSAENETUNREACH
10055 => "ENOBUFS", // WSAENOBUFS
161 => "ENOENT", // ERROR_BAD_PATHNAME
267 => "ENOENT", // ERROR_DIRECTORY
203 => "ENOENT", // ERROR_ENVVAR_NOT_FOUND
2 => "ENOENT", // ERROR_FILE_NOT_FOUND
123 => "ENOENT", // ERROR_INVALID_NAME
15 => "ENOENT", // ERROR_INVALID_DRIVE
4392 => "ENOENT", // ERROR_INVALID_REPARSE_DATA
126 => "ENOENT", // ERROR_MOD_NOT_FOUND
3 => "ENOENT", // ERROR_PATH_NOT_FOUND
11001 => "ENOENT", // WSAHOST_NOT_FOUND
11004 => "ENOENT", // WSANO_DATA
8 => "ENOMEM", // ERROR_NOT_ENOUGH_MEMORY
14 => "ENOMEM", // ERROR_OUTOFMEMORY
82 => "ENOSPC", // ERROR_CANNOT_MAKE
112 => "ENOSPC", // ERROR_DISK_FULL
277 => "ENOSPC", // ERROR_EA_TABLE_FULL
1100 => "ENOSPC", // ERROR_END_OF_MEDIA
39 => "ENOSPC", // ERROR_HANDLE_DISK_FULL
2250 => "ENOTCONN", // ERROR_NOT_CONNECTED
10057 => "ENOTCONN", // WSAENOTCONN
145 => "ENOTEMPTY", // ERROR_DIR_NOT_EMPTY
10038 => "ENOTSOCK", // WSAENOTSOCK
50 => "ENOTSUP", // ERROR_NOT_SUPPORTED
5 => "EPERM", // ERROR_ACCESS_DENIED
1314 => "EPERM", // ERROR_PRIVILEGE_NOT_HELD
230 => "EPIPE", // ERROR_BAD_PIPE
232 => "EPIPE", // ERROR_NO_DATA
233 => "EPIPE", // ERROR_PIPE_NOT_CONNECTED
10058 => "EPIPE", // WSAESHUTDOWN
10043 => "EPROTONOSUPPORT", // WSAEPROTONOSUPPORT
19 => "EROFS", // ERROR_WRITE_PROTECT
121 => "ETIMEDOUT", // ERROR_SEM_TIMEOUT
10060 => "ETIMEDOUT", // WSAETIMEDOUT
17 => "EXDEV", // ERROR_NOT_SAME_DEVICE
1 => "EISDIR", // ERROR_INVALID_FUNCTION
208 => "E2BIG", // ERROR_META_EXPANSION_TOO_LONG
10044 => "ESOCKTNOSUPPORT", // WSAESOCKTNOSUPPORT
_ => "",
}
}