Skip to content

Commit a333e71

Browse files
apapirovskiMylesBorins
authored andcommitted
errors: consistent format for error message
Consistently use printf-style strings for error messages that do not need a custom argument order or processing of arguments. Backport-PR-URL: #17624 PR-URL: #16904 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent dcd87ac commit a333e71

File tree

3 files changed

+93
-41
lines changed

3 files changed

+93
-41
lines changed

lib/internal/errors.js

+27-41
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint documented-errors: "error" */
22
/* eslint alphabetize-errors: "error" */
3+
/* eslint prefer-util-format-errors: "error" */
34

45
'use strict';
56

@@ -146,8 +147,8 @@ module.exports = exports = {
146147
// Note: Please try to keep these in alphabetical order
147148
E('ERR_ARG_NOT_ITERABLE', '%s must be iterable');
148149
E('ERR_ASSERTION', '%s');
149-
E('ERR_ASYNC_CALLBACK', (name) => `${name} must be a function`);
150-
E('ERR_ASYNC_TYPE', (s) => `Invalid name for async "type": ${s}`);
150+
E('ERR_ASYNC_CALLBACK', '%s must be a function');
151+
E('ERR_ASYNC_TYPE', 'Invalid name for async "type": %s');
151152
E('ERR_BUFFER_OUT_OF_BOUNDS', bufferOutOfBounds);
152153
E('ERR_BUFFER_TOO_LARGE',
153154
`Cannot create a Buffer larger than 0x${kMaxLength.toString(16)} bytes`);
@@ -169,12 +170,10 @@ E('ERR_CRYPTO_INVALID_DIGEST', 'Invalid digest: %s');
169170
E('ERR_CRYPTO_SIGN_KEY_REQUIRED', 'No key provided to sign');
170171
E('ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH',
171172
'Input buffers must have the same length');
172-
E('ERR_DNS_SET_SERVERS_FAILED', (err, servers) =>
173-
`c-ares failed to set servers: "${err}" [${servers}]`);
173+
E('ERR_DNS_SET_SERVERS_FAILED', 'c-ares failed to set servers: "%s" [%s]');
174174
E('ERR_ENCODING_INVALID_ENCODED_DATA',
175-
(enc) => `The encoded data was not valid for encoding ${enc}`);
176-
E('ERR_ENCODING_NOT_SUPPORTED',
177-
(enc) => `The "${enc}" encoding is not supported`);
175+
'The encoded data was not valid for encoding %s');
176+
E('ERR_ENCODING_NOT_SUPPORTED', 'The "%s" encoding is not supported');
178177
E('ERR_FALSY_VALUE_REJECTION', 'Promise was rejected with falsy value');
179178
E('ERR_HTTP2_CONNECT_AUTHORITY',
180179
':authority header is required for CONNECT requests');
@@ -194,10 +193,9 @@ E('ERR_HTTP2_HEADERS_AFTER_RESPOND',
194193
'Cannot specify additional headers after response initiated');
195194
E('ERR_HTTP2_HEADERS_OBJECT', 'Headers must be an object');
196195
E('ERR_HTTP2_HEADERS_SENT', 'Response has already been initiated.');
197-
E('ERR_HTTP2_HEADER_REQUIRED',
198-
(name) => `The ${name} header is required`);
196+
E('ERR_HTTP2_HEADER_REQUIRED', 'The %s header is required');
199197
E('ERR_HTTP2_HEADER_SINGLE_VALUE',
200-
(name) => `Header field "${name}" must have only a single value`);
198+
'Header field "%s" must have only a single value');
201199
E('ERR_HTTP2_INFO_HEADERS_AFTER_RESPOND',
202200
'Cannot send informational headers after the HTTP message has been sent');
203201
E('ERR_HTTP2_INFO_STATUS_NOT_ALLOWED',
@@ -206,23 +204,23 @@ E('ERR_HTTP2_INVALID_CONNECTION_HEADERS',
206204
'HTTP/1 Connection specific headers are forbidden: "%s"');
207205
E('ERR_HTTP2_INVALID_HEADER_VALUE', 'Invalid value "%s" for header "%s"');
208206
E('ERR_HTTP2_INVALID_INFO_STATUS',
209-
(code) => `Invalid informational status code: ${code}`);
207+
'Invalid informational status code: %s');
210208
E('ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH',
211209
'Packed settings length must be a multiple of six');
212210
E('ERR_HTTP2_INVALID_PSEUDOHEADER',
213-
(name) => `"${name}" is an invalid pseudoheader or is used incorrectly`);
211+
'"%s" is an invalid pseudoheader or is used incorrectly');
214212
E('ERR_HTTP2_INVALID_SESSION', 'The session has been destroyed');
215213
E('ERR_HTTP2_INVALID_SETTING_VALUE',
216-
(name, value) => `Invalid value for setting "${name}": ${value}`);
214+
'Invalid value for setting "%s": %s');
217215
E('ERR_HTTP2_INVALID_STREAM', 'The stream has been destroyed');
218216
E('ERR_HTTP2_MAX_PENDING_SETTINGS_ACK',
219-
(max) => `Maximum number of pending settings acknowledgements (${max})`);
217+
'Maximum number of pending settings acknowledgements (%s)');
220218
E('ERR_HTTP2_NO_SOCKET_MANIPULATION',
221219
'HTTP/2 sockets should not be directly manipulated (e.g. read and written)');
222220
E('ERR_HTTP2_OUT_OF_STREAMS',
223221
'No stream ID is available because maximum stream ID has been reached');
224222
E('ERR_HTTP2_PAYLOAD_FORBIDDEN',
225-
(code) => `Responses with ${code} status must not have a payload`);
223+
'Responses with %s status must not have a payload');
226224
E('ERR_HTTP2_PING_CANCEL', 'HTTP2 ping cancelled');
227225
E('ERR_HTTP2_PING_LENGTH', 'HTTP2 ping payload must be 8 bytes');
228226
E('ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED', 'Cannot set HTTP/2 pseudo-headers');
@@ -232,19 +230,15 @@ E('ERR_HTTP2_SOCKET_BOUND',
232230
'The socket is already bound to an Http2Session');
233231
E('ERR_HTTP2_STATUS_101',
234232
'HTTP status code 101 (Switching Protocols) is forbidden in HTTP/2');
235-
E('ERR_HTTP2_STATUS_INVALID',
236-
(code) => `Invalid status code: ${code}`);
233+
E('ERR_HTTP2_STATUS_INVALID', 'Invalid status code: %s');
237234
E('ERR_HTTP2_STREAM_CLOSED', 'The stream is already closed');
238-
E('ERR_HTTP2_STREAM_ERROR',
239-
(code) => `Stream closed with error code ${code}`);
235+
E('ERR_HTTP2_STREAM_ERROR', 'Stream closed with error code %s');
240236
E('ERR_HTTP2_STREAM_SELF_DEPENDENCY', 'A stream cannot depend on itself');
241-
E('ERR_HTTP2_UNSUPPORTED_PROTOCOL',
242-
(protocol) => `protocol "${protocol}" is unsupported.`);
237+
E('ERR_HTTP2_UNSUPPORTED_PROTOCOL', 'protocol "%s" is unsupported.');
243238
E('ERR_HTTP_HEADERS_SENT',
244239
'Cannot %s headers after they are sent to the client');
245240
E('ERR_HTTP_INVALID_CHAR', 'Invalid character in statusMessage.');
246-
E('ERR_HTTP_INVALID_STATUS_CODE',
247-
(originalStatusCode) => `Invalid status code: ${originalStatusCode}`);
241+
E('ERR_HTTP_INVALID_STATUS_CODE', 'Invalid status code: %s');
248242
E('ERR_HTTP_TRAILER_INVALID',
249243
'Trailers are invalid with this transfer encoding');
250244
E('ERR_INDEX_OUT_OF_RANGE', 'Index out of range');
@@ -253,16 +247,14 @@ E('ERR_INSPECTOR_CLOSED', 'Session was closed');
253247
E('ERR_INSPECTOR_NOT_AVAILABLE', 'Inspector is not available');
254248
E('ERR_INSPECTOR_NOT_CONNECTED', 'Session is not connected');
255249
E('ERR_INVALID_ARG_TYPE', invalidArgType);
256-
E('ERR_INVALID_ARG_VALUE',
257-
(name, value) => {
258-
return `The value "${String(value)}" is invalid for argument "${name}"`;
259-
});
250+
E('ERR_INVALID_ARG_VALUE', (name, value) =>
251+
`The value "${String(value)}" is invalid for argument "${name}"`);
260252
E('ERR_INVALID_ARRAY_LENGTH',
261253
(name, len, actual) => {
262254
internalAssert(typeof actual === 'number', 'actual must be a number');
263255
return `The array "${name}" (length ${actual}) must be of length ${len}.`;
264256
});
265-
E('ERR_INVALID_ASYNC_ID', (type, id) => `Invalid ${type} value: ${id}`);
257+
E('ERR_INVALID_ASYNC_ID', 'Invalid %s value: %s');
266258
E('ERR_INVALID_BUFFER_SIZE', 'Buffer size must be a multiple of %s');
267259
E('ERR_INVALID_CALLBACK', 'Callback must be a function');
268260
E('ERR_INVALID_CHAR', invalidChar);
@@ -277,15 +269,12 @@ E('ERR_INVALID_FILE_URL_PATH', 'File URL path %s');
277269
E('ERR_INVALID_HANDLE_TYPE', 'This handle type cannot be sent');
278270
E('ERR_INVALID_HTTP_TOKEN', '%s must be a valid HTTP token ["%s"]');
279271
E('ERR_INVALID_IP_ADDRESS', 'Invalid IP address: %s');
280-
E('ERR_INVALID_OPT_VALUE',
281-
(name, value) => {
282-
return `The value "${String(value)}" is invalid for option "${name}"`;
283-
});
272+
E('ERR_INVALID_OPT_VALUE', (name, value) =>
273+
`The value "${String(value)}" is invalid for option "${name}"`);
284274
E('ERR_INVALID_OPT_VALUE_ENCODING',
285-
(value) => `The value "${String(value)}" is invalid for option "encoding"`);
275+
'The value "%s" is invalid for option "encoding"');
286276
E('ERR_INVALID_PERFORMANCE_MARK', 'The "%s" performance mark has not been set');
287-
E('ERR_INVALID_PROTOCOL', (protocol, expectedProtocol) =>
288-
`Protocol "${protocol}" not supported. Expected "${expectedProtocol}"`);
277+
E('ERR_INVALID_PROTOCOL', 'Protocol "%s" not supported. Expected "%s"');
289278
E('ERR_INVALID_REPL_EVAL_CONFIG',
290279
'Cannot specify both "breakEvalOnSigint" and "eval" for REPL');
291280
E('ERR_INVALID_SYNC_FORK_INPUT',
@@ -325,8 +314,7 @@ E('ERR_SOCKET_BAD_BUFFER_SIZE', 'Buffer size must be a positive integer');
325314
E('ERR_SOCKET_BAD_PORT', 'Port should be > 0 and < 65536. Received %s.');
326315
E('ERR_SOCKET_BAD_TYPE',
327316
'Bad socket type specified. Valid types are: udp4, udp6');
328-
E('ERR_SOCKET_BUFFER_SIZE',
329-
(reason) => `Could not get or set buffer size: ${reason}`);
317+
E('ERR_SOCKET_BUFFER_SIZE', 'Could not get or set buffer size: %s');
330318
E('ERR_SOCKET_CANNOT_SEND', 'Unable to send data');
331319
E('ERR_SOCKET_CLOSED', 'Socket is closed');
332320
E('ERR_SOCKET_DGRAM_NOT_RUNNING', 'Not running');
@@ -341,8 +329,7 @@ E('ERR_STREAM_WRAP', 'Stream has StringDecoder set or is in objectMode');
341329
E('ERR_STREAM_WRITE_AFTER_END', 'write after end');
342330
E('ERR_TLS_CERT_ALTNAME_INVALID',
343331
'Hostname/IP does not match certificate\'s altnames: %s');
344-
E('ERR_TLS_DH_PARAM_SIZE', (size) =>
345-
`DH parameter size ${size} is less than 2048`);
332+
E('ERR_TLS_DH_PARAM_SIZE', 'DH parameter size %s is less than 2048');
346333
E('ERR_TLS_HANDSHAKE_TIMEOUT', 'TLS handshake timeout');
347334
E('ERR_TLS_RENEGOTIATION_FAILED', 'Failed to renegotiate');
348335
E('ERR_TLS_REQUIRED_SERVER_NAME',
@@ -352,8 +339,7 @@ E('ERR_TRANSFORM_ALREADY_TRANSFORMING',
352339
'Calling transform done when still transforming');
353340
E('ERR_TRANSFORM_WITH_LENGTH_0',
354341
'Calling transform done when writableState.length != 0');
355-
E('ERR_UNESCAPED_CHARACTERS',
356-
(name) => `${name} contains unescaped characters`);
342+
E('ERR_UNESCAPED_CHARACTERS', '%s contains unescaped characters');
357343
E('ERR_UNHANDLED_ERROR',
358344
(err) => {
359345
const msg = 'Unhandled error.';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
/* eslint-disable no-template-curly-in-string */
4+
5+
require('../common');
6+
7+
const RuleTester = require('../../tools/eslint').RuleTester;
8+
const rule = require('../../tools/eslint-rules/prefer-util-format-errors');
9+
10+
new RuleTester({ parserOptions: { ecmaVersion: 6 } })
11+
.run('prefer-util-format-errors', rule, {
12+
valid: [
13+
'E(\'ABC\', \'abc\');',
14+
'E(\'ABC\', (arg1, arg2) => `${arg2}${arg1}`);',
15+
'E(\'ABC\', (arg1, arg2) => `${arg1}{arg2.something}`);',
16+
'E(\'ABC\', (arg1, arg2) => fn(arg1, arg2));'
17+
],
18+
invalid: [
19+
{
20+
code: 'E(\'ABC\', (arg1, arg2) => `${arg1}${arg2}`);',
21+
errors: [{
22+
message: 'Please use a printf-like formatted string that ' +
23+
'util.format can consume.'
24+
}]
25+
}
26+
]
27+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict';
2+
3+
const errMsg = 'Please use a printf-like formatted string that util.format' +
4+
' can consume.';
5+
6+
function isArrowFunctionWithTemplateLiteral(node) {
7+
return node.type === 'ArrowFunctionExpression' &&
8+
node.body.type === 'TemplateLiteral';
9+
}
10+
11+
function isDefiningError(node) {
12+
return node.expression &&
13+
node.expression.type === 'CallExpression' &&
14+
node.expression.callee &&
15+
node.expression.callee.name === 'E';
16+
}
17+
18+
module.exports = {
19+
create: function(context) {
20+
return {
21+
ExpressionStatement: function(node) {
22+
if (!isDefiningError(node))
23+
return;
24+
25+
const msg = node.expression.arguments[1];
26+
if (!isArrowFunctionWithTemplateLiteral(msg))
27+
return;
28+
29+
const { expressions } = msg.body;
30+
const hasSequentialParams = msg.params.every((param, index) => {
31+
const expr = expressions[index];
32+
return expr && expr.type === 'Identifier' && param.name === expr.name;
33+
});
34+
if (hasSequentialParams)
35+
context.report(msg, errMsg);
36+
}
37+
};
38+
}
39+
};

0 commit comments

Comments
 (0)