From f601721851bdd64ee5b40bd3d408df063691b425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Schwarzkopf=20Bal=C3=A1zs?= Date: Tue, 22 Sep 2020 22:07:35 +0200 Subject: feat(std/node): implement getSystemErrorName() (#7624) --- std/node/_errors.ts | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) (limited to 'std/node/_errors.ts') diff --git a/std/node/_errors.ts b/std/node/_errors.ts index 2321bb24f..864f1252b 100644 --- a/std/node/_errors.ts +++ b/std/node/_errors.ts @@ -21,7 +21,10 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. +import { unreachable } from "../testing/asserts.ts"; + // It will do so until we'll have Node errors completely ported (#5944): + // Ref: https://github.com/nodejs/node/blob/50d28d4b3a616b04537feff014aa70437f064e30/lib/internal/errors.js#L251 // Ref: https://github.com/nodejs/node/blob/50d28d4b3a616b04537feff014aa70437f064e30/lib/internal/errors.js#L299 // Ref: https://github.com/nodejs/node/blob/50d28d4b3a616b04537feff014aa70437f064e30/lib/internal/errors.js#L325 @@ -43,6 +46,299 @@ class ERR_INVALID_ARG_TYPE extends TypeError { } } +class ERR_OUT_OF_RANGE extends RangeError { + code = "ERR_OUT_OF_RANGE"; + + constructor(str: string, range: string, received: unknown) { + super( + `The value of "${str}" is out of range. It must be ${range}. Received ${received}`, + ); + + const { name } = this; + // Add the error code to the name to include it in the stack trace. + this.name = `${name} [${this.code}]`; + // Access the stack to generate the error message including the error code from the name. + this.stack; + // Reset the name to the actual name. + this.name = name; + } +} + export const codes = { ERR_INVALID_ARG_TYPE, + ERR_OUT_OF_RANGE, }; + +// In Node these values are coming from libuv: +// Ref: https://github.com/libuv/libuv/blob/v1.x/include/uv/errno.h +// Ref: https://github.com/nodejs/node/blob/524123fbf064ff64bb6fcd83485cfc27db932f68/lib/internal/errors.js#L383 +// Since there is no easy way to port code from libuv and these maps are +// changing very rarely, we simply extract them from Node and store here. + +// Note +// Run the following to get the map: +// $ node -e "console.log(process.binding('uv').getErrorMap())" +// This setup automatically exports maps from both "win", "linux" & darwin: +// https://github.com/schwarzkopfb/node_errno_map + +type ErrMapData = Array<[number, [string, string]]>; + +const windows: ErrMapData = [ + [-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"]], + [-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"]], +]; + +const darwin: ErrMapData = [ + [-7, ["E2BIG", "argument list too long"]], + [-13, ["EACCES", "permission denied"]], + [-48, ["EADDRINUSE", "address already in use"]], + [-49, ["EADDRNOTAVAIL", "address not available"]], + [-47, ["EAFNOSUPPORT", "address family not supported"]], + [-35, ["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"]], + [-37, ["EALREADY", "connection already in progress"]], + [-9, ["EBADF", "bad file descriptor"]], + [-16, ["EBUSY", "resource busy or locked"]], + [-89, ["ECANCELED", "operation canceled"]], + [-4080, ["ECHARSET", "invalid Unicode character"]], + [-53, ["ECONNABORTED", "software caused connection abort"]], + [-61, ["ECONNREFUSED", "connection refused"]], + [-54, ["ECONNRESET", "connection reset by peer"]], + [-39, ["EDESTADDRREQ", "destination address required"]], + [-17, ["EEXIST", "file already exists"]], + [-14, ["EFAULT", "bad address in system call argument"]], + [-27, ["EFBIG", "file too large"]], + [-65, ["EHOSTUNREACH", "host is unreachable"]], + [-4, ["EINTR", "interrupted system call"]], + [-22, ["EINVAL", "invalid argument"]], + [-5, ["EIO", "i/o error"]], + [-56, ["EISCONN", "socket is already connected"]], + [-21, ["EISDIR", "illegal operation on a directory"]], + [-62, ["ELOOP", "too many symbolic links encountered"]], + [-24, ["EMFILE", "too many open files"]], + [-40, ["EMSGSIZE", "message too long"]], + [-63, ["ENAMETOOLONG", "name too long"]], + [-50, ["ENETDOWN", "network is down"]], + [-51, ["ENETUNREACH", "network is unreachable"]], + [-23, ["ENFILE", "file table overflow"]], + [-55, ["ENOBUFS", "no buffer space available"]], + [-19, ["ENODEV", "no such device"]], + [-2, ["ENOENT", "no such file or directory"]], + [-12, ["ENOMEM", "not enough memory"]], + [-4056, ["ENONET", "machine is not on the network"]], + [-42, ["ENOPROTOOPT", "protocol not available"]], + [-28, ["ENOSPC", "no space left on device"]], + [-78, ["ENOSYS", "function not implemented"]], + [-57, ["ENOTCONN", "socket is not connected"]], + [-20, ["ENOTDIR", "not a directory"]], + [-66, ["ENOTEMPTY", "directory not empty"]], + [-38, ["ENOTSOCK", "socket operation on non-socket"]], + [-45, ["ENOTSUP", "operation not supported on socket"]], + [-1, ["EPERM", "operation not permitted"]], + [-32, ["EPIPE", "broken pipe"]], + [-100, ["EPROTO", "protocol error"]], + [-43, ["EPROTONOSUPPORT", "protocol not supported"]], + [-41, ["EPROTOTYPE", "protocol wrong type for socket"]], + [-34, ["ERANGE", "result too large"]], + [-30, ["EROFS", "read-only file system"]], + [-58, ["ESHUTDOWN", "cannot send after transport endpoint shutdown"]], + [-29, ["ESPIPE", "invalid seek"]], + [-3, ["ESRCH", "no such process"]], + [-60, ["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"]], + [-64, ["EHOSTDOWN", "host is down"]], + [-4030, ["EREMOTEIO", "remote I/O error"]], + [-25, ["ENOTTY", "inappropriate ioctl for device"]], + [-79, ["EFTYPE", "inappropriate file type or format"]], + [-92, ["EILSEQ", "illegal byte sequence"]], +]; + +const linux: ErrMapData = [ + [-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"]], + [-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"]], +]; + +const { os } = Deno.build; +export const errorMap = new Map( + os === "windows" + ? windows + : os === "darwin" + ? darwin + : os === "linux" + ? linux + : unreachable(), +); -- cgit v1.2.3