Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: remove unused internal error constructors #19203

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CPP_STYLE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,13 @@ env->SetMethod(target, "foo", Foo);
exports.foo = function(str) {
// Prefer doing the type-checks in JavaScript
if (typeof str !== 'string') {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'str', 'string');
throw new errors.codes.ERR_INVALID_ARG_TYPE('str', 'string');
}

const ctx = {};
const result = binding.foo(str, ctx);
if (ctx.code !== undefined) {
throw new errors.Error('ERR_ERROR_NAME', ctx.code);
throw new errors.codes.ERR_ERROR_NAME(ctx.code);
}
return result;
};
Expand Down
93 changes: 27 additions & 66 deletions doc/guides/using-internal-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ considered a `semver-major` change.

## Using internal/errors.js

The `internal/errors` module exposes three custom `Error` classes that
are intended to replace existing `Error` objects within the Node.js source.
The `internal/errors` module exposes all custom errors as subclasses of the
builtin errors. After being added, an error can be found in the `codes` object.

For instance, an existing `Error` such as:

Expand All @@ -32,15 +32,15 @@ Can be replaced by first adding a new error key into the `internal/errors.js`
file:

```js
E('FOO', 'Expected string received %s');
E('FOO', 'Expected string received %s', TypeError);
```

Then replacing the existing `new TypeError` in the code:

```js
const errors = require('internal/errors');
const { FOO } = require('internal/errors').codes;
// ...
const err = new errors.TypeError('FOO', type);
const err = new FOO(type);
```

## Adding new errors
Expand All @@ -49,16 +49,33 @@ New static error codes are added by modifying the `internal/errors.js` file
and appending the new error codes to the end using the utility `E()` method.

```js
E('EXAMPLE_KEY1', 'This is the error value');
E('EXAMPLE_KEY2', (a, b) => `${a} ${b}`);
E('EXAMPLE_KEY1', 'This is the error value', TypeError);
E('EXAMPLE_KEY2', (a, b) => `${a} ${b}`, RangeError);
```

The first argument passed to `E()` is the static identifier. The second
argument is either a String with optional `util.format()` style replacement
tags (e.g. `%s`, `%d`), or a function returning a String. The optional
additional arguments passed to the `errors.message()` function (which is
used by the `errors.Error`, `errors.TypeError` and `errors.RangeError` classes),
will be used to format the error message.
will be used to format the error message. The third argument is the base class
that the new error will extend.

It is possible to create multiple derived
classes by providing additional arguments. The other ones will be exposed as
properties of the main class:

<!-- eslint-disable no-unreachable -->
```js
E('EXAMPLE_KEY', 'Error message', TypeError, RangeError);

// In another module
const { EXAMPLE_KEY } = require('internal/errors').codes;
// TypeError
throw new EXAMPLE_KEY();
// RangeError
throw new EXAMPLE_KEY.RangeError();
```

## Documenting new errors

Expand Down Expand Up @@ -115,65 +132,9 @@ likely be required.

## API

### Class: errors.Error(key[, args...])

* `key` {string} The static error identifier
* `args...` {any} Zero or more optional arguments

```js
const errors = require('internal/errors');

const arg1 = 'foo';
const arg2 = 'bar';
const myError = new errors.Error('KEY', arg1, arg2);
throw myError;
```

The specific error message for the `myError` instance will depend on the
associated value of `KEY` (see "Adding new errors").

The `myError` object will have a `code` property equal to the `key` and a
`name` property equal to `` `Error [${key}]` ``.

### Class: errors.TypeError(key[, args...])

* `key` {string} The static error identifier
* `args...` {any} Zero or more optional arguments

```js
const errors = require('internal/errors');

const arg1 = 'foo';
const arg2 = 'bar';
const myError = new errors.TypeError('KEY', arg1, arg2);
throw myError;
```

The specific error message for the `myError` instance will depend on the
associated value of `KEY` (see "Adding new errors").

The `myError` object will have a `code` property equal to the `key` and a
`name` property equal to `` `TypeError [${key}]` ``.

### Class: errors.RangeError(key[, args...])

* `key` {string} The static error identifier
* `args...` {any} Zero or more optional arguments

```js
const errors = require('internal/errors');

const arg1 = 'foo';
const arg2 = 'bar';
const myError = new errors.RangeError('KEY', arg1, arg2);
throw myError;
```

The specific error message for the `myError` instance will depend on the
associated value of `KEY` (see "Adding new errors").
### Object: errors.codes

The `myError` object will have a `code` property equal to the `key` and a
`name` property equal to `` `RangeError [${key}]` ``.
Exposes all internal error classes to be used by Node.js APIs.

### Method: errors.message(key, args)

Expand Down
6 changes: 4 additions & 2 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const fs = exports;
const { Buffer } = require('buffer');
const errors = require('internal/errors');
const {
ERR_FS_WATCHER_ALREADY_STARTED,
ERR_FS_WATCHER_NOT_STARTED,
ERR_INVALID_ARG_TYPE,
ERR_INVALID_CALLBACK,
ERR_OUT_OF_RANGE
Expand Down Expand Up @@ -1349,7 +1351,7 @@ FSWatcher.prototype.start = function(filename,
encoding) {
lazyAssert()(this._handle instanceof FSEvent, 'handle must be a FSEvent');
if (this._handle.initialized) {
throw new errors.Error('ERR_FS_WATCHER_ALREADY_STARTED');
throw new ERR_FS_WATCHER_ALREADY_STARTED();
}

filename = getPathFromURL(filename);
Expand All @@ -1373,7 +1375,7 @@ FSWatcher.prototype.start = function(filename,
FSWatcher.prototype.close = function() {
lazyAssert()(this._handle instanceof FSEvent, 'handle must be a FSEvent');
if (!this._handle.initialized) {
throw new errors.Error('ERR_FS_WATCHER_NOT_STARTED');
throw new ERR_FS_WATCHER_NOT_STARTED();
}
this._handle.close();
};
Expand Down
14 changes: 5 additions & 9 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ function makeNodeErrorWithCode(Base, key) {
// *only* to allow for testing.
function E(sym, val, def, ...otherClasses) {
messages.set(sym, val);
if (def === undefined) return;
def = makeNodeErrorWithCode(def, sym);
if (otherClasses.length !== 0) {
otherClasses.forEach((clazz) => {
Expand Down Expand Up @@ -572,23 +571,20 @@ module.exports = exports = {
exceptionWithHostPort,
uvException,
message,
Error: makeNodeError(Error),
TypeError: makeNodeError(TypeError),
RangeError: makeNodeError(RangeError),
URIError: makeNodeError(URIError),
AssertionError,
SystemError,
codes,
E, // This is exported only to facilitate testing.
errorCache: new Map() // This is in here only to facilitate testing.
};

// To declare an error message, use the E(sym, val) function above. The sym
// To declare an error message, use the E(sym, val, def) function above. The sym
// must be an upper case string. The val can be either a function or a string.
// The def must be an error class.
// The return value of the function must be a string.
// Examples:
// E('EXAMPLE_KEY1', 'This is the error value');
// E('EXAMPLE_KEY2', (a, b) => return `${a} ${b}`);
// E('EXAMPLE_KEY1', 'This is the error value', Error);
// E('EXAMPLE_KEY2', (a, b) => return `${a} ${b}`, RangeError);
//
// Once an error code has been assigned, the code itself MUST NOT change and
// any given error code must never be reused to identify a different error.
Expand Down Expand Up @@ -858,7 +854,6 @@ E('ERR_STREAM_UNSHIFT_AFTER_END_EVENT',
'stream.unshift() after end event', Error);
E('ERR_STREAM_WRAP', 'Stream has StringDecoder set or is in objectMode', Error);
E('ERR_STREAM_WRITE_AFTER_END', 'write after end', Error);
E('ERR_SYSTEM_ERROR', sysError);
E('ERR_TLS_CERT_ALTNAME_INVALID',
'Hostname/IP does not match certificate\'s altnames: %s', Error);
E('ERR_TLS_DH_PARAM_SIZE', 'DH parameter size %s is less than 2048', Error);
Expand Down Expand Up @@ -934,6 +929,7 @@ function sysError(code, syscall, path, dest,
}
return message;
}
messages.set('ERR_SYSTEM_ERROR', sysError);

function invalidArgType(name, expected, actual) {
internalAssert(name, 'name is required');
Expand Down
Loading