mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 23:59:59 -05:00
feat(std/node): implement getSystemErrorName() (#7624)
This commit is contained in:
parent
dd1cd4d952
commit
f601721851
3 changed files with 352 additions and 2 deletions
|
@ -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<number, [string, string]>(
|
||||
os === "windows"
|
||||
? windows
|
||||
: os === "darwin"
|
||||
? darwin
|
||||
: os === "linux"
|
||||
? linux
|
||||
: unreachable(),
|
||||
);
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
export { promisify } from "./_util/_util_promisify.ts";
|
||||
export { callbackify } from "./_util/_util_callbackify.ts";
|
||||
import { codes, errorMap } from "./_errors.ts";
|
||||
import * as types from "./_util/_util_types.ts";
|
||||
|
||||
export { types };
|
||||
|
||||
const NumberIsSafeInteger = Number.isSafeInteger;
|
||||
const {
|
||||
ERR_OUT_OF_RANGE,
|
||||
ERR_INVALID_ARG_TYPE,
|
||||
} = codes;
|
||||
|
||||
const DEFAULT_INSPECT_OPTIONS = {
|
||||
showHidden: false,
|
||||
depth: 2,
|
||||
|
@ -90,6 +96,16 @@ export function isPrimitive(value: unknown): boolean {
|
|||
);
|
||||
}
|
||||
|
||||
export function getSystemErrorName(code: number): string | undefined {
|
||||
if (typeof code !== "number") {
|
||||
throw new ERR_INVALID_ARG_TYPE("err", "number", code);
|
||||
}
|
||||
if (code >= 0 || !NumberIsSafeInteger(code)) {
|
||||
throw new ERR_OUT_OF_RANGE("err", "a negative integer", code);
|
||||
}
|
||||
return errorMap.get(code)?.[0];
|
||||
}
|
||||
|
||||
import { _TextDecoder, _TextEncoder } from "./_utils.ts";
|
||||
|
||||
/** The global TextDecoder */
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { assert, assertEquals } from "../testing/asserts.ts";
|
||||
|
||||
import {
|
||||
assert,
|
||||
assertEquals,
|
||||
assertStrictEquals,
|
||||
assertThrows,
|
||||
} from "../testing/asserts.ts";
|
||||
import { stripColor } from "../fmt/colors.ts";
|
||||
import * as util from "./util.ts";
|
||||
|
||||
|
@ -182,3 +188,35 @@ Deno.test({
|
|||
assert(util.types.isDate(new Date()));
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "[util] getSystemErrorName()",
|
||||
fn() {
|
||||
type FnTestInvalidArg = (code?: unknown) => void;
|
||||
|
||||
assertThrows(
|
||||
() => (util.getSystemErrorName as FnTestInvalidArg)(),
|
||||
TypeError,
|
||||
);
|
||||
assertThrows(
|
||||
() => (util.getSystemErrorName as FnTestInvalidArg)(1),
|
||||
RangeError,
|
||||
);
|
||||
|
||||
assertStrictEquals(util.getSystemErrorName(-424242), undefined);
|
||||
|
||||
switch (Deno.build.os) {
|
||||
case "windows":
|
||||
assertStrictEquals(util.getSystemErrorName(-4091), "EADDRINUSE");
|
||||
break;
|
||||
|
||||
case "darwin":
|
||||
assertStrictEquals(util.getSystemErrorName(-48), "EADDRINUSE");
|
||||
break;
|
||||
|
||||
case "linux":
|
||||
assertStrictEquals(util.getSystemErrorName(-98), "EADDRINUSE");
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue