Skip to content

Commit 5a0e379

Browse files
committed
errors: move functions to error code
This makes sure the functions are actually directly beneath the specification of an error code. That way it is not necessary to jump around when looking at the functionality. PR-URL: nodejs#20486 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
1 parent b304096 commit 5a0e379

File tree

1 file changed

+92
-97
lines changed

1 file changed

+92
-97
lines changed

lib/internal/errors.js

Lines changed: 92 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,26 @@ function isStackOverflowError(err) {
407407
err.message === maxStack_ErrorMessage;
408408
}
409409

410+
function oneOf(expected, thing) {
411+
assert(typeof thing === 'string', '`thing` has to be of type string');
412+
if (Array.isArray(expected)) {
413+
const len = expected.length;
414+
assert(len > 0,
415+
'At least one expected value needs to be specified');
416+
expected = expected.map((i) => String(i));
417+
if (len > 2) {
418+
return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` +
419+
expected[len - 1];
420+
} else if (len === 2) {
421+
return `one of ${thing} ${expected[0]} or ${expected[1]}`;
422+
} else {
423+
return `of ${thing} ${expected[0]}`;
424+
}
425+
} else {
426+
return `of ${thing} ${String(expected)}`;
427+
}
428+
}
429+
410430
module.exports = {
411431
dnsException,
412432
errnoException,
@@ -441,7 +461,15 @@ E('ERR_ARG_NOT_ITERABLE', '%s must be iterable', TypeError);
441461
E('ERR_ASSERTION', '%s', Error);
442462
E('ERR_ASYNC_CALLBACK', '%s must be a function', TypeError);
443463
E('ERR_ASYNC_TYPE', 'Invalid name for async "type": %s', TypeError);
444-
E('ERR_BUFFER_OUT_OF_BOUNDS', bufferOutOfBounds, RangeError);
464+
E('ERR_BUFFER_OUT_OF_BOUNDS',
465+
// Using a default argument here is important so the argument is not counted
466+
// towards `Function#length`.
467+
(name = undefined) => {
468+
if (name) {
469+
return `"${name}" is outside of buffer bounds`;
470+
}
471+
return 'Attempt to write outside buffer bounds';
472+
}, RangeError);
445473
E('ERR_BUFFER_TOO_LARGE',
446474
`Cannot create a Buffer larger than 0x${kMaxLength.toString(16)} bytes`,
447475
RangeError);
@@ -579,7 +607,32 @@ E('ERR_INSPECTOR_CLOSED', 'Session was closed', Error);
579607
E('ERR_INSPECTOR_NOT_AVAILABLE', 'Inspector is not available', Error);
580608
E('ERR_INSPECTOR_NOT_CONNECTED', 'Session is not connected', Error);
581609
E('ERR_INVALID_ADDRESS_FAMILY', 'Invalid address family: %s', RangeError);
582-
E('ERR_INVALID_ARG_TYPE', invalidArgType, TypeError);
610+
E('ERR_INVALID_ARG_TYPE',
611+
(name, expected, actual) => {
612+
assert(typeof name === 'string', "'name' must be a string");
613+
614+
// determiner: 'must be' or 'must not be'
615+
let determiner;
616+
if (typeof expected === 'string' && expected.startsWith('not ')) {
617+
determiner = 'must not be';
618+
expected = expected.replace(/^not /, '');
619+
} else {
620+
determiner = 'must be';
621+
}
622+
623+
let msg;
624+
if (name.endsWith(' argument')) {
625+
// For cases like 'first argument'
626+
msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`;
627+
} else {
628+
const type = name.includes('.') ? 'property' : 'argument';
629+
msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`;
630+
}
631+
632+
// TODO(BridgeAR): Improve the output by showing `null` and similar.
633+
msg += `. Received type ${typeof actual}`;
634+
return msg;
635+
}, TypeError);
583636
E('ERR_INVALID_ARG_VALUE', (name, value, reason = 'is invalid') => {
584637
let inspected = util.inspect(value);
585638
if (inspected.length > 128) {
@@ -591,7 +644,16 @@ E('ERR_INVALID_ASYNC_ID', 'Invalid %s value: %s', RangeError);
591644
E('ERR_INVALID_BUFFER_SIZE',
592645
'Buffer size must be a multiple of %s', RangeError);
593646
E('ERR_INVALID_CALLBACK', 'Callback must be a function', TypeError);
594-
E('ERR_INVALID_CHAR', invalidChar, TypeError);
647+
E('ERR_INVALID_CHAR',
648+
// Using a default argument here is important so the argument is not counted
649+
// towards `Function#length`.
650+
(name, field = undefined) => {
651+
let msg = `Invalid character in ${name}`;
652+
if (field !== undefined) {
653+
msg += ` ["${field}"]`;
654+
}
655+
return msg;
656+
}, TypeError);
595657
E('ERR_INVALID_CURSOR_POS',
596658
'Cannot set cursor row without setting its column', TypeError);
597659
E('ERR_INVALID_FD',
@@ -640,7 +702,26 @@ E('ERR_IPC_DISCONNECTED', 'IPC channel is already disconnected', Error);
640702
E('ERR_IPC_ONE_PIPE', 'Child process can have only one IPC pipe', Error);
641703
E('ERR_IPC_SYNC_FORK', 'IPC cannot be used with synchronous forks', Error);
642704
E('ERR_METHOD_NOT_IMPLEMENTED', 'The %s method is not implemented', Error);
643-
E('ERR_MISSING_ARGS', missingArgs, TypeError);
705+
E('ERR_MISSING_ARGS',
706+
(...args) => {
707+
assert(args.length > 0, 'At least one arg needs to be specified');
708+
let msg = 'The ';
709+
const len = args.length;
710+
args = args.map((a) => `"${a}"`);
711+
switch (len) {
712+
case 1:
713+
msg += `${args[0]} argument`;
714+
break;
715+
case 2:
716+
msg += `${args[0]} and ${args[1]} arguments`;
717+
break;
718+
default:
719+
msg += args.slice(0, len - 1).join(', ');
720+
msg += `, and ${args[len - 1]} arguments`;
721+
break;
722+
}
723+
return `${msg} must be specified`;
724+
}, TypeError);
644725
E('ERR_MISSING_MODULE', 'Cannot find module %s', Error);
645726
E('ERR_MODULE_RESOLUTION_LEGACY',
646727
'%s not found by import in %s.' +
@@ -661,7 +742,13 @@ E('ERR_NO_CRYPTO',
661742
E('ERR_NO_ICU',
662743
'%s is not supported on Node.js compiled without ICU', TypeError);
663744
E('ERR_NO_LONGER_SUPPORTED', '%s is no longer supported', Error);
664-
E('ERR_OUT_OF_RANGE', outOfRange, RangeError);
745+
E('ERR_OUT_OF_RANGE',
746+
(name, range, value) => {
747+
let msg = `The value of "${name}" is out of range.`;
748+
if (range !== undefined) msg += ` It must be ${range}.`;
749+
msg += ` Received ${value}`;
750+
return msg;
751+
}, RangeError);
665752
E('ERR_REQUIRE_ESM', 'Must use import to load ES Module: %s', Error);
666753
E('ERR_SCRIPT_EXECUTION_INTERRUPTED',
667754
'Script execution was interrupted by `SIGINT`', Error);
@@ -758,95 +845,3 @@ E('ERR_VM_MODULE_NOT_MODULE',
758845
'Provided module is not an instance of Module', Error);
759846
E('ERR_VM_MODULE_STATUS', 'Module status %s', Error);
760847
E('ERR_ZLIB_INITIALIZATION_FAILED', 'Initialization failed', Error);
761-
762-
function invalidArgType(name, expected, actual) {
763-
assert(typeof name === 'string', "'name' must be a string");
764-
765-
// determiner: 'must be' or 'must not be'
766-
let determiner;
767-
if (typeof expected === 'string' && expected.startsWith('not ')) {
768-
determiner = 'must not be';
769-
expected = expected.replace(/^not /, '');
770-
} else {
771-
determiner = 'must be';
772-
}
773-
774-
let msg;
775-
if (name.endsWith(' argument')) {
776-
// For cases like 'first argument'
777-
msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`;
778-
} else {
779-
const type = name.includes('.') ? 'property' : 'argument';
780-
msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`;
781-
}
782-
783-
// TODO(BridgeAR): Improve the output by showing `null` and similar.
784-
msg += `. Received type ${typeof actual}`;
785-
return msg;
786-
}
787-
788-
function missingArgs(...args) {
789-
assert(args.length > 0, 'At least one arg needs to be specified');
790-
let msg = 'The ';
791-
const len = args.length;
792-
args = args.map((a) => `"${a}"`);
793-
switch (len) {
794-
case 1:
795-
msg += `${args[0]} argument`;
796-
break;
797-
case 2:
798-
msg += `${args[0]} and ${args[1]} arguments`;
799-
break;
800-
default:
801-
msg += args.slice(0, len - 1).join(', ');
802-
msg += `, and ${args[len - 1]} arguments`;
803-
break;
804-
}
805-
return `${msg} must be specified`;
806-
}
807-
808-
function oneOf(expected, thing) {
809-
assert(typeof thing === 'string', '`thing` has to be of type string');
810-
if (Array.isArray(expected)) {
811-
const len = expected.length;
812-
assert(len > 0,
813-
'At least one expected value needs to be specified');
814-
expected = expected.map((i) => String(i));
815-
if (len > 2) {
816-
return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` +
817-
expected[len - 1];
818-
} else if (len === 2) {
819-
return `one of ${thing} ${expected[0]} or ${expected[1]}`;
820-
} else {
821-
return `of ${thing} ${expected[0]}`;
822-
}
823-
} else {
824-
return `of ${thing} ${String(expected)}`;
825-
}
826-
}
827-
828-
// Using a default argument here is important so the argument is not counted
829-
// towards `Function#length`.
830-
function bufferOutOfBounds(name = undefined) {
831-
if (name) {
832-
return `"${name}" is outside of buffer bounds`;
833-
}
834-
return 'Attempt to write outside buffer bounds';
835-
}
836-
837-
// Using a default argument here is important so the argument is not counted
838-
// towards `Function#length`.
839-
function invalidChar(name, field = undefined) {
840-
let msg = `Invalid character in ${name}`;
841-
if (field !== undefined) {
842-
msg += ` ["${field}"]`;
843-
}
844-
return msg;
845-
}
846-
847-
function outOfRange(name, range, value) {
848-
let msg = `The value of "${name}" is out of range.`;
849-
if (range !== undefined) msg += ` It must be ${range}.`;
850-
msg += ` Received ${value}`;
851-
return msg;
852-
}

0 commit comments

Comments
 (0)