Skip to content

Commit 8272c22

Browse files
committed
errors: implement new error handling
This implements a function based system. Instead of passing in the error code as first argument, the error code itself is a error class. It already contains the correct error type, so while adding a new error no one has to think about the error type anymore. In case a single error code has more than one error type, the error class has properties for the non default error types. Those can be used as fallback. This prevents typos, makes the implementation easier and it is less verbose when writing the code for a new error. The implementation itself does not interfere with the old implementation. So the old and the new system can co-exist and it is possible to slowly migrate the old ones to the new system. PR-URL: nodejs#18857 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
1 parent 887a2ba commit 8272c22

File tree

1 file changed

+50
-6
lines changed

1 file changed

+50
-6
lines changed

lib/internal/errors.js

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
const kCode = Symbol('code');
1414
const kInfo = Symbol('info');
1515
const messages = new Map();
16+
const codes = {};
1617

1718
var green = '';
1819
var red = '';
@@ -86,6 +87,54 @@ function makeNodeError(Base) {
8687
};
8788
}
8889

90+
function makeNodeErrorWithCode(Base, key) {
91+
return class NodeError extends Base {
92+
constructor(...args) {
93+
super(message(key, args));
94+
}
95+
96+
get name() {
97+
return `${super.name} [${key}]`;
98+
}
99+
100+
set name(value) {
101+
defineProperty(this, 'name', {
102+
configurable: true,
103+
enumerable: true,
104+
value,
105+
writable: true
106+
});
107+
}
108+
109+
get code() {
110+
return key;
111+
}
112+
113+
set code(value) {
114+
defineProperty(this, 'code', {
115+
configurable: true,
116+
enumerable: true,
117+
value,
118+
writable: true
119+
});
120+
}
121+
};
122+
}
123+
124+
// Utility function for registering the error codes. Only used here. Exported
125+
// *only* to allow for testing.
126+
function E(sym, val, def, ...otherClasses) {
127+
messages.set(sym, val);
128+
if (def === undefined) return;
129+
def = makeNodeErrorWithCode(def, sym);
130+
if (otherClasses.length !== 0) {
131+
otherClasses.forEach((clazz) => {
132+
def[clazz.name] = makeNodeErrorWithCode(clazz, sym);
133+
});
134+
}
135+
codes[sym] = def;
136+
}
137+
89138
function lazyBuffer() {
90139
if (buffer === undefined)
91140
buffer = require('buffer').Buffer;
@@ -367,12 +416,6 @@ function message(key, args) {
367416
return String(fmt.apply(null, args));
368417
}
369418

370-
// Utility function for registering the error codes. Only used here. Exported
371-
// *only* to allow for testing.
372-
function E(sym, val) {
373-
messages.set(sym, typeof val === 'function' ? val : String(val));
374-
}
375-
376419
/**
377420
* This creates an error compatible with errors produced in the C++
378421
* function UVException using a context object with data assembled in C++.
@@ -523,6 +566,7 @@ module.exports = exports = {
523566
URIError: makeNodeError(URIError),
524567
AssertionError,
525568
SystemError,
569+
codes,
526570
E, // This is exported only to facilitate testing.
527571
errorCache: new Map() // This is in here only to facilitate testing.
528572
};

0 commit comments

Comments
 (0)