diff --git a/.eslintrc b/.eslintrc index 33a7919d88c9ef..38b59b2c2cb090 100644 --- a/.eslintrc +++ b/.eslintrc @@ -13,6 +13,7 @@ ecmaFeatures: objectLiteralShorthandProperties: true octalLiterals: true templateStrings: true + restParams: true rules: # Possible Errors diff --git a/lib/_debug_agent.js b/lib/_debug_agent.js index 63c50357894b08..b2d642c7497cf7 100644 --- a/lib/_debug_agent.js +++ b/lib/_debug_agent.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const assert = require('assert'); const net = require('net'); const util = require('util'); @@ -20,7 +21,7 @@ exports.start = function start() { agent.listen(process._debugAPI.port, function() { var addr = this.address(); - process._rawDebug('Debugger listening on port %d', addr.port); + process._rawDebug(I18N(I18N.DEBUGAGENT_LISTENING, addr.port)); process._debugAPI.notifyListen(); }); @@ -57,7 +58,7 @@ function Agent() { }; this.clients = []; - assert(this.binding, 'Debugger agent running without bindings!'); + assert(this.binding, I18N(I18N.DEBUGAGENT_NO_BINDINGS)); } util.inherits(Agent, net.Server); @@ -132,7 +133,7 @@ Client.prototype._transform = function _transform(data, enc, cb) { // Header-name: header-value\r\n var match = this.buffer.match(/^([^:\s\r\n]+)\s*:\s*([^\s\r\n]+)\r\n/); if (!match) - return this.destroy('Expected header, but failed to parse it'); + return this.destroy(I18N(I18N.DEBUGAGENT_EXPECTED_HEADER)); this.headers[match[1].toLowerCase()] = match[2]; @@ -140,7 +141,7 @@ Client.prototype._transform = function _transform(data, enc, cb) { } else { var len = this.headers['content-length']; if (len === undefined) - return this.destroy('Expected content-length'); + return this.destroy(I18N(I18N.DEBUGAGENT_EXPECTED_CONTENT_LENGTH)); len = len | 0; if (Buffer.byteLength(this.buffer) < len) diff --git a/lib/_debugger.js b/lib/_debugger.js index e1f0f812a5d2b5..d269a50fbb6dcd 100644 --- a/lib/_debugger.js +++ b/lib/_debugger.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const internalUtil = require('internal/util'); const util = require('util'); const path = require('path'); @@ -12,13 +13,16 @@ const assert = require('assert'); const spawn = require('child_process').spawn; const Buffer = require('buffer').Buffer; +const USAGE = `${I18N(I18N.DEBUGGER_USAGE)}: + node debug script.js + node debug : + node debug -p `; + exports.start = function(argv, stdin, stdout) { argv || (argv = process.argv.slice(2)); if (argv.length < 1) { - console.error('Usage: node debug script.js'); - console.error(' node debug :'); - console.error(' node debug -p '); + console.error(USAGE); process.exit(1); } @@ -32,8 +36,8 @@ exports.start = function(argv, stdin, stdout) { stdin.resume(); process.on('uncaughtException', function(e) { - internalUtil.error('There was an internal error in Node\'s debugger. ' + - 'Please report this bug.'); + // Report internal error + internalUtil.error(I18N(I18N.DEBUGGER_ERROR)); console.error(e.message); console.error(e.stack); if (interface_.child) interface_.child.kill(); @@ -126,7 +130,7 @@ Protocol.prototype.execute = function(d) { break; default: - throw new Error('Unknown state'); + throw new I18N.Error(I18N.DEBUGGER_UNKNOWN_STATE); } }; @@ -135,8 +139,7 @@ Protocol.prototype.serialize = function(req) { req.type = 'request'; req.seq = this.reqSeq++; var json = JSON.stringify(req); - return 'Content-Length: ' + Buffer.byteLength(json, 'utf8') + - '\r\n\r\n' + json; + return `Content-Length: ${Buffer.byteLength(json, 'utf8')}\r\n\r\n${json}`; }; @@ -521,7 +524,7 @@ Client.prototype.mirrorObject = function(handle, depth, cb) { cb = cb || function() {}; this.reqLookup(propertyRefs, function(err, res) { if (err) { - internalUtil.error('problem with reqLookup'); + internalUtil.error(I18N(I18N.DEBUGGER_PROBLEM_REQLOOKUP)); cb(null, handle); return; } @@ -598,7 +601,8 @@ Client.prototype.fullTrace = function(cb) { cb = cb || function() {}; this.reqBacktrace(function(err, trace) { if (err) return cb(err); - if (trace.totalFrames <= 0) return cb(Error('No frames')); + if (trace.totalFrames <= 0) + return cb(new I18N.Error(I18N.DEBUGGER_NO_FRAMES)); var refs = []; @@ -669,11 +673,8 @@ const commands = [ ] ]; - -var helpMessage = 'Commands: ' + commands.map(function(group) { - return group.join(', '); -}).join(',\n'); - +var cmdList = commands.map((group) => group.join(', ')).join(',\n'); +var helpMessage = `${I18N(I18N.DEBUGGER_COMMANDS)}: ${cmdList}`; function SourceUnderline(sourceText, position, repl) { if (!sourceText) return ''; @@ -695,7 +696,9 @@ function SourceUnderline(sourceText, position, repl) { function SourceInfo(body) { - var result = body.exception ? 'exception in ' : 'break in '; + var result = body.exception ? + I18N(I18N.DEBUGGER_EXCEPTION_IN) : + I18N(I18N.DEBUGGER_BREAK_IN); if (body.script) { if (body.script.name) { @@ -932,7 +935,7 @@ Interface.prototype.handleBreak = function(r) { // Internal method for checking connection state Interface.prototype.requireConnection = function() { if (!this.client) { - this.error('App isn\'t running... Try `run` instead'); + this.error(I18N(I18N.DEBUGGER_APP_NOT_RUNNING)); return false; } return true; @@ -1038,7 +1041,7 @@ Interface.prototype.run = function() { var callback = arguments[0]; if (this.child) { - this.error('App is already running... Try `restart` instead'); + this.error(I18N(I18N.DEBUGGER_APP_RUNNING)); callback && callback(true); } else { this.trySpawn(callback); @@ -1094,7 +1097,7 @@ Interface.prototype.list = function(delta) { self.pause(); client.reqSource(from, to, function(err, res) { if (err || !res) { - self.error('You can\'t list source code right now'); + self.error(I18N(I18N.DEBUGGER_CANNOT_LIST_SOURCE)); self.resume(); return; } @@ -1153,13 +1156,13 @@ Interface.prototype.backtrace = function() { self.pause(); client.fullTrace(function(err, bt) { if (err) { - self.error('Can\'t request backtrace now'); + self.error(I18N(I18N.DEBUGGER_CANNOT_REQUEST_BACKTRACE)); self.resume(); return; } if (bt.totalFrames == 0) { - self.print('(empty stack)'); + self.print(I18N(I18N.DEBUGGER_EMPTY_STACK)); } else { var trace = [], firstFrameNative = bt.frames[0].script.isNative; @@ -1296,7 +1299,7 @@ Interface.prototype.watchers = function() { function wait() { if (--waiting === 0) { - if (verbose) self.print('Watchers:'); + if (verbose) self.print(`${I18N(I18N.DEBUGGER_WATCHERS)}: `); self._watchers.forEach(function(watcher, i) { self.print(leftPad(i, ' ', self._watchers.length - 1) + @@ -1348,8 +1351,7 @@ Interface.prototype.setBreakpoint = function(script, line, } if (script === undefined) { - this.print('Cannot determine the current script, ' + - 'make sure the debugged process is paused.'); + this.print(I18N(I18N.DEBUGGER_CANNOT_DETERMINE_SCRIPT)); return; } @@ -1378,8 +1380,10 @@ Interface.prototype.setBreakpoint = function(script, line, scriptId = script; } - if (ambiguous) return this.error('Script name is ambiguous'); - if (line <= 0) return this.error('Line should be a positive value'); + if (ambiguous) + return this.error(I18N(I18N.DEBUGGER_SCRIPT_NAME_AMBIGUOUS)); + if (line <= 0) + return this.error(I18N(I18N.DEBUGGER_LINE_POSITIVE)); var req; if (scriptId) { @@ -1390,7 +1394,7 @@ Interface.prototype.setBreakpoint = function(script, line, condition: condition }; } else { - this.print('Warning: script \'' + script + '\' was not loaded yet.'); + this.print(I18N(I18N.DEBUGGER_SCRIPT_NOT_LOADED, script)); var escapedPath = script.replace(/([/\\.?*()^${}|[\]])/g, '\\$1'); var scriptPathRegex = '^(.*[\\/\\\\])?' + escapedPath + '$'; req = { @@ -1472,15 +1476,14 @@ Interface.prototype.clearBreakpoint = function(script, line) { } } - if (ambiguous) return this.error('Script name is ambiguous'); + if (ambiguous) + return this.error(I18N(I18N.DEBUGGER_SCRIPT_NAME_AMBIGUOUS)); - if (scriptId === undefined) { - return this.error('Script ' + script + ' not found'); - } + if (scriptId === undefined) + return this.error(I18N(I18N.DEBUGGER_SCRIPT_NOT_FOUND, script)); - if (breakpoint === undefined) { - return this.error('Breakpoint not found on line ' + line); - } + if (breakpoint === undefined) + return this.error(I18N(I18N.DEBUGGER_BREAKPOINT_NOT_FOUND, line)); var self = this, req = { @@ -1560,7 +1563,7 @@ Interface.prototype.repl = function() { var self = this; - self.print('Press Ctrl + C to leave debug repl'); + self.print(I18N(I18N.DEBUGGER_REPL_EXIT)); // Don't display any default messages var listeners = this.repl.rli.listeners('SIGINT').slice(0); @@ -1671,7 +1674,7 @@ Interface.prototype.trySpawn = function(cb) { process._debugProcess(pid); } catch (e) { if (e.code === 'ESRCH') { - internalUtil.error(`Target process: ${pid} doesn't exist.`); + internalUtil.error(I18N(I18N.DEBUGGER_TARGET_PROCESS, pid)); process.exit(1); } throw e; @@ -1702,17 +1705,18 @@ Interface.prototype.trySpawn = function(cb) { connectionAttempts = 0; client.once('ready', function() { - self.stdout.write(' ok\n'); + self.stdout.write(` ${I18N(I18N.DEBUGGER_READY)}\n`); // Restore breakpoints breakpoints.forEach(function(bp) { - self.print('Restoring breakpoint ' + bp.scriptReq + ':' + bp.line); + self.print(`${I18N(I18N.DEBUGGER_RESTORING_BREAKPOINT)} ` + + `${bp.scriptReq}:${bp.line}`); self.setBreakpoint(bp.scriptReq, bp.line, bp.condition, true); }); client.on('close', function() { self.pause(); - self.print('program terminated'); + self.print(I18N(I18N.DEBUGGER_PROGRAM_TERMINATED)); self.resume(); self.client = null; self.killChild(); @@ -1724,7 +1728,8 @@ Interface.prototype.trySpawn = function(cb) { client.on('unhandledResponse', function(res) { self.pause(); - self.print('\nunhandled res:' + JSON.stringify(res)); + self.print(`\n${I18N(I18N.DEBUGGER_UNHANDLED_RESPONSE)}: ` + + `${JSON.stringify(res)}`); self.resume(); }); @@ -1740,7 +1745,7 @@ Interface.prototype.trySpawn = function(cb) { function connectError() { // If it's failed to connect 10 times then print failed message if (connectionAttempts >= 10) { - internalUtil.error(' failed to connect, please retry'); + internalUtil.error(I18N(I18N.DEBUGGER_CONNECTION_FAILED)); process.exit(1); } setTimeout(attemptConnect, 500); @@ -1753,11 +1758,13 @@ Interface.prototype.trySpawn = function(cb) { } if (isRemote) { - self.print('connecting to ' + host + ':' + port + ' ..', true); + self.print(`${I18N(I18N.DEBUGGER_CONNECTING)} ${host}:${port} ..`, + true); attemptConnect(); } else { this.child.stderr.once('data', function() { - self.print('connecting to ' + host + ':' + port + ' ..', true); + self.print(`${I18N(I18N.DEBUGGER_CONNECTING)} ${host}:${port} ..`, + true); setImmediate(attemptConnect); }); } diff --git a/lib/_http_agent.js b/lib/_http_agent.js index ddb1c5bfff9b63..3778928e33e422 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -1,9 +1,10 @@ 'use strict'; +const I18N = require('internal/messages'); +const debug = I18N.debuglog('http'); const net = require('net'); const util = require('util'); const EventEmitter = require('events'); -const debug = util.debuglog('http'); // New Agent code. @@ -42,7 +43,7 @@ function Agent(options) { self.on('free', function(socket, options) { var name = self.getName(options); - debug('agent.on(free)', name); + debug(I18N.HTTP_AGENT_DEBUG_ONFREE, name); if (!socket.destroyed && self.requests[name] && self.requests[name].length) { @@ -126,7 +127,7 @@ Agent.prototype.addRequest = function(req, options) { if (freeLen) { // we have a free socket, so use that. var socket = this.freeSockets[name].shift(); - debug('have free socket'); + debug(I18N.HTTP_AGENT_DEBUG_FREE_SOCKET); // don't leak if (!this.freeSockets[name].length) @@ -136,11 +137,11 @@ Agent.prototype.addRequest = function(req, options) { req.onSocket(socket); this.sockets[name].push(socket); } else if (sockLen < this.maxSockets) { - debug('call onSocket', sockLen, freeLen); + debug(I18N.HTTP_AGENT_DEBUG_CALL_ONSOCKET, sockLen, freeLen); // If we are under maxSockets create a new one. req.onSocket(this.createSocket(req, options)); } else { - debug('wait for socket'); + debug(I18N.HTTP_AGENT_DEBUG_WAIT_FOR_SOCKET); // We are over limit so we'll add it to the queue. if (!this.requests[name]) { this.requests[name] = []; @@ -167,14 +168,14 @@ Agent.prototype.createSocket = function(req, options) { var name = self.getName(options); options._agentKey = name; - debug('createConnection', name, options); + debug(I18N.HTTP_AGENT_DEBUG_CREATE_CONNECTION, name, options); options.encoding = null; var s = self.createConnection(options); if (!self.sockets[name]) { self.sockets[name] = []; } this.sockets[name].push(s); - debug('sockets', name, this.sockets[name].length); + debug(I18N.HTTP_AGENT_DEBUG_SOCKETS, name, this.sockets[name].length); function onFree() { self.emit('free', s, options); @@ -182,7 +183,7 @@ Agent.prototype.createSocket = function(req, options) { s.on('free', onFree); function onClose(err) { - debug('CLIENT socket onClose'); + debug(I18N.HTTP_AGENT_DEBUG_CLIENT_CLOSE); // This is the only place where sockets get removed from the Agent. // If you want to remove a socket from the pool, just close it. // All socket errors end in a close event anyway. @@ -194,7 +195,7 @@ Agent.prototype.createSocket = function(req, options) { // We need this function for cases like HTTP 'upgrade' // (defined by WebSockets) where we need to remove a socket from the // pool because it'll be locked up indefinitely - debug('CLIENT socket onRemove'); + debug(I18N.HTTP_AGENT_DEBUG_CLIENT_REMOVE); self.removeSocket(s, options); s.removeListener('close', onClose); s.removeListener('free', onFree); @@ -206,7 +207,7 @@ Agent.prototype.createSocket = function(req, options) { Agent.prototype.removeSocket = function(s, options) { var name = this.getName(options); - debug('removeSocket', name, 'destroyed:', s.destroyed); + debug(I18N.HTTP_AGENT_DEBUG_DESTROYED, name, s.destroyed); var sets = [this.sockets]; // If the socket was destroyed, remove it from the free buffers too. @@ -228,7 +229,7 @@ Agent.prototype.removeSocket = function(s, options) { } if (this.requests[name] && this.requests[name].length) { - debug('removeSocket, have a request, make a socket'); + debug(I18N.HTTP_AGENT_DEBUG_MAKE_SOCKET); var req = this.requests[name][0]; // If we have pending requests and a socket gets closed make a new one this.createSocket(req, options).emit('free'); diff --git a/lib/_http_client.js b/lib/_http_client.js index 34072f8f996840..58853cf7dcc8e2 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const util = require('util'); const net = require('net'); const url = require('url'); @@ -22,7 +23,8 @@ function ClientRequest(options, cb) { if (typeof options === 'string') { options = url.parse(options); if (!options.hostname) { - throw new Error('Unable to determine the domain name'); + // Unable to determine the domain name + throw new I18N.Error(I18N.HTTP_CLIENT_DOMAIN_NAME); } } else { options = util._extend({}, options); @@ -50,10 +52,10 @@ function ClientRequest(options, cb) { // well, and b) possibly too restrictive for real-world usage. That's // why it only scans for spaces because those are guaranteed to create // an invalid request. - throw new TypeError('Request path contains unescaped characters'); + throw new I18N.TypeError(I18N.HTTP_CLIENT_UNESCAPED_PATH); } else if (protocol !== expectedProtocol) { - throw new Error('Protocol "' + protocol + '" not supported. ' + - 'Expected "' + expectedProtocol + '"'); + throw new I18N.Error(I18N.HTTP_CLIENT_UNEXPECTED_PROTOCOL, + protocol, expectedProtocol); } const defaultPort = options.defaultPort || @@ -70,7 +72,7 @@ function ClientRequest(options, cb) { var method = self.method = (options.method || 'GET').toUpperCase(); if (!common._checkIsHttpToken(method)) { - throw new TypeError('Method must be a valid HTTP token'); + throw new I18N.TypeError(I18N.HTTP_INVALID_TOKEN, 'method'); } self.path = options.path || '/'; if (cb) { @@ -142,7 +144,7 @@ function ClientRequest(options, cb) { if (options.createConnection) { self.onSocket(options.createConnection(options)); } else { - debug('CLIENT use net.createConnection', options); + debug(I18N.HTTP_CLIENT_DEBUG_CLIENT_CREATE, options); self.onSocket(net.createConnection(options)); } } @@ -203,7 +205,7 @@ function emitAbortNT(self) { function createHangUpError() { - var error = new Error('socket hang up'); + var error = new I18N.Error(I18N.NET_SOCKET_HANGUP); error.code = 'ECONNRESET'; return error; } @@ -212,7 +214,7 @@ function createHangUpError() { function socketCloseListener() { var socket = this; var req = socket._httpMessage; - debug('HTTP socket close'); + debug(I18N.HTTP_CLIENT_DEBUG_SOCKET_CLOSE); // Pull through final chunk, if anything is buffered. // the ondata function will handle it properly, and this @@ -256,7 +258,7 @@ function socketCloseListener() { function socketErrorListener(err) { var socket = this; var req = socket._httpMessage; - debug('SOCKET ERROR:', err.message, err.stack); + debug(I18N.HTTP_CLIENT_DEBUG_SOCKET_ERROR, err.message, err.stack); if (req) { req.emit('error', err); @@ -282,7 +284,7 @@ function socketErrorListener(err) { function freeSocketErrorListener(err) { var socket = this; - debug('SOCKET ERROR on FREE socket:', err.message, err.stack); + debug(I18N.HTTP_CLIENT_DEBUG_SOCKET_ERROR_FREE, err.message, err.stack); socket.destroy(); socket.emit('agentRemove'); } @@ -314,7 +316,7 @@ function socketOnData(d) { var ret = parser.execute(d); if (ret instanceof Error) { - debug('parse error'); + debug(I18N.HTTP_CLIENT_DEBUG_PARSE_ERROR); freeParser(parser, req, socket); socket.destroy(); req.emit('error', ret); @@ -371,11 +373,11 @@ function parserOnIncomingClient(res, shouldKeepAlive) { // propagate "domain" setting... if (req.domain && !res.domain) { - debug('setting "res.domain"'); + debug(I18N.HTTP_CLIENT_DEBUG_SETTING_RESDOMAIN); res.domain = req.domain; } - debug('AGENT incoming response!'); + debug(I18N.HTTP_CLIENT_DEBUG_INCOMING_RESPONSE); if (req.res) { // We already have a response object, this means the server @@ -397,7 +399,7 @@ function parserOnIncomingClient(res, shouldKeepAlive) { // to the content-length of the entity-body had the request // been a GET. var isHeadResponse = req.method === 'HEAD'; - debug('AGENT isHeadResponse', isHeadResponse); + debug(I18N.HTTP_CLIENT_DEBUG_ISHEAD, isHeadResponse); if (res.statusCode === 100) { // restart the parser, as this is a continue message. @@ -441,12 +443,12 @@ function responseOnEnd() { if (!req.shouldKeepAlive) { if (socket.writable) { - debug('AGENT socket.destroySoon()'); + debug(I18N.HTTP_CLIENT_DEBUG_SOCKET_DESTROYSOON); socket.destroySoon(); } assert(!socket.writable); } else { - debug('AGENT socket keep-alive'); + debug(I18N.HTTP_CLIENT_DEBUG_KEEPALIVE); if (req.timeoutCb) { socket.setTimeout(0, req.timeoutCb); req.timeoutCb = null; diff --git a/lib/_http_common.js b/lib/_http_common.js index 7e23ae98e90175..2e63de03154541 100644 --- a/lib/_http_common.js +++ b/lib/_http_common.js @@ -8,7 +8,8 @@ const IncomingMessage = incoming.IncomingMessage; const readStart = incoming.readStart; const readStop = incoming.readStop; -const debug = require('util').debuglog('http'); +const I18N = require('internal/messages'); +const debug = I18N.debuglog('http'); exports.debug = debug; exports.CRLF = '\r\n'; diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index 450975b72a1033..b6822c8db21644 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const assert = require('assert').ok; const Stream = require('stream'); const timers = require('timers'); @@ -9,6 +10,7 @@ const Buffer = require('buffer').Buffer; const common = require('_http_common'); const CRLF = common.CRLF; +const crlf_buf = new Buffer(CRLF); const chunkExpression = common.chunkExpression; const debug = common.debug; @@ -227,7 +229,7 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) { // Date header if (this.sendDate === true && state.sentDateHeader === false) { - state.messageHeader += 'Date: ' + utcDate() + CRLF; + state.messageHeader += `Date: ${utcDate()}${CRLF}`; } // Force the connection to close when the response is a 204 No Content or @@ -244,8 +246,7 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) { var statusCode = this.statusCode; if ((statusCode === 204 || statusCode === 304) && this.chunkedEncoding === true) { - debug(statusCode + ' response should not use chunked encoding,' + - ' closing connection.'); + debug(I18N.HTTP_OUTGOING_DEBUG_NOT_USE_CHUNKED, statusCode); this.chunkedEncoding = false; this.shouldKeepAlive = false; } @@ -260,10 +261,10 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) { this.useChunkedEncodingByDefault || this.agent); if (shouldSendKeepAlive) { - state.messageHeader += 'Connection: keep-alive\r\n'; + state.messageHeader += `Connection: keep-alive${CRLF}`; } else { this._last = true; - state.messageHeader += 'Connection: close\r\n'; + state.messageHeader += `Connection: close${CRLF}`; } } @@ -278,16 +279,15 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) { if (!state.sentTrailer && !this._removedHeader['content-length'] && typeof this._contentLength === 'number') { - state.messageHeader += 'Content-Length: ' + this._contentLength + - '\r\n'; + state.messageHeader += `Content-Length: ${this._contentLength}${CRLF}`; } else if (!this._removedHeader['transfer-encoding']) { - state.messageHeader += 'Transfer-Encoding: chunked\r\n'; + state.messageHeader += `Transfer-Encoding: chunked${CRLF}`; this.chunkedEncoding = true; } else { // We should only be able to get here if both Content-Length and // Transfer-Encoding are removed by the user. // See: test/parallel/test-http-remove-header-stays-removed.js - debug('Both Content-Length and Transfer-Encoding are removed'); + debug(I18N.HTTP_OUTGOING_DEBUG_BOTH_REMOVED); } } } @@ -302,11 +302,10 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) { function storeHeader(self, state, field, value) { if (!common._checkIsHttpToken(field)) { - throw new TypeError( - 'Header name must be a valid HTTP Token ["' + field + '"]'); + throw new I18N.TypeError(I18N.HTTP_INVALID_TOKEN, 'field'); } value = escapeHeaderValue(value); - state.messageHeader += field + ': ' + value + CRLF; + state.messageHeader += `${field}: ${value}${CRLF}`; if (connectionExpression.test(field)) { state.sentConnectionHeader = true; @@ -334,14 +333,13 @@ function storeHeader(self, state, field, value) { OutgoingMessage.prototype.setHeader = function(name, value) { if (!common._checkIsHttpToken(name)) - throw new TypeError( - 'Header name must be a valid HTTP Token ["' + name + '"]'); + throw new I18N.TypeError(I18N.HTTP_INVALID_TOKEN, 'name'); if (typeof name !== 'string') - throw new TypeError('"name" should be a string in setHeader(name, value)'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'name', 'string'); if (value === undefined) - throw new Error('"value" required in setHeader("' + name + '", value)'); + throw new I18N.Error(I18N.REQUIRED_ARG, 'value'); if (this._header) - throw new Error('Can\'t set headers after they are sent'); + throw new I18N.Error(I18N.HTTP_OUTGOING_SET_AFTER_SEND); if (this._headers === null) this._headers = {}; @@ -356,9 +354,8 @@ OutgoingMessage.prototype.setHeader = function(name, value) { OutgoingMessage.prototype.getHeader = function(name) { - if (arguments.length < 1) { - throw new Error('"name" argument is required for getHeader(name)'); - } + if (arguments.length < 1) + throw new I18N.Error(I18N.REQUIRED_ARG, 'name'); if (!this._headers) return; @@ -368,13 +365,11 @@ OutgoingMessage.prototype.getHeader = function(name) { OutgoingMessage.prototype.removeHeader = function(name) { - if (arguments.length < 1) { - throw new Error('"name" argument is required for removeHeader(name)'); - } + if (arguments.length < 1) + throw new I18N.Error(I18N.REQUIRED_ARG, 'name'); - if (this._header) { - throw new Error('Can\'t remove headers after they are sent'); - } + if (this._header) + throw new I18N.Error(I18N.HTTP_OUTGOING_REMOVE_AFTER_SEND); var key = name.toLowerCase(); @@ -391,9 +386,8 @@ OutgoingMessage.prototype.removeHeader = function(name) { OutgoingMessage.prototype._renderHeaders = function() { - if (this._header) { - throw new Error('Can\'t render headers after they are sent to the client'); - } + if (this._header) + throw I18N(I18N.HTTP_OUTGOING_RENDER_AFTER_SEND); var headersMap = this._headers; if (!headersMap) return {}; @@ -419,9 +413,9 @@ Object.defineProperty(OutgoingMessage.prototype, 'headersSent', { OutgoingMessage.prototype.write = function(chunk, encoding, callback) { if (this.finished) { - var err = new Error('write after end'); - process.nextTick(writeAfterEndNT, this, err, callback); - + process.nextTick(writeAfterEndNT, this, + new I18N.Error(I18N.WRITE_AFTER_END), + callback); return true; } @@ -430,14 +424,12 @@ OutgoingMessage.prototype.write = function(chunk, encoding, callback) { } if (!this._hasBody) { - debug('This type of response MUST NOT have a body. ' + - 'Ignoring write() calls.'); + debug(I18N.HTTP_OUTGOING_DEBUG_IGNORING_WRITE); return true; } - if (typeof chunk !== 'string' && !(chunk instanceof Buffer)) { - throw new TypeError('First argument must be a string or Buffer'); - } + if (typeof chunk !== 'string' && !(chunk instanceof Buffer)) + throw new I18N.TypeError(I18N.FIRST_ARGUMENT_STRING_OR_BUFFER); // If we get an empty string or buffer, then just do nothing, and @@ -473,7 +465,7 @@ OutgoingMessage.prototype.write = function(chunk, encoding, callback) { ret = this._send(chunk, encoding, callback); } - debug('write ret = ' + ret); + debug(I18N.HTTP_OUTGOING_DEBUG_WRITE_RET, ret); return ret; }; @@ -511,18 +503,12 @@ OutgoingMessage.prototype.addTrailers = function(headers) { field = key; value = headers[key]; } - if (!common._checkIsHttpToken(field)) { - throw new TypeError( - 'Trailer name must be a valid HTTP Token ["' + field + '"]'); - } - this._trailer += field + ': ' + escapeHeaderValue(value) + CRLF; + if (!common._checkIsHttpToken(field)) + throw new I18N.TypeError(I18N.HTTP_INVALID_TOKEN, 'field'); + this._trailer += `${field}: ${escapeHeaderValue(value)}${CRLF}`; } }; - -const crlf_buf = new Buffer('\r\n'); - - OutgoingMessage.prototype.end = function(data, encoding, callback) { if (typeof data === 'function') { callback = data; @@ -532,13 +518,11 @@ OutgoingMessage.prototype.end = function(data, encoding, callback) { encoding = null; } - if (data && typeof data !== 'string' && !(data instanceof Buffer)) { - throw new TypeError('First argument must be a string or Buffer'); - } + if (data && typeof data !== 'string' && !(data instanceof Buffer)) + throw new I18N.TypeError(I18N.FIRST_ARGUMENT_STRING_OR_BUFFER); - if (this.finished) { + if (this.finished) return false; - } var self = this; function finish() { @@ -561,8 +545,7 @@ OutgoingMessage.prototype.end = function(data, encoding, callback) { } if (data && !this._hasBody) { - debug('This type of response MUST NOT have a body. ' + - 'Ignoring data passed to end().'); + debug(I18N.HTTP_OUTGOING_DEBUG_IGNORING_END_DATA); data = null; } @@ -576,7 +559,7 @@ OutgoingMessage.prototype.end = function(data, encoding, callback) { } if (this._hasBody && this.chunkedEncoding) { - ret = this._send('0\r\n' + this._trailer + '\r\n', 'binary', finish); + ret = this._send(`0${CRLF}${this._trailer}${CRLF}`, 'binary', finish); } else { // Force a flush, HACK. ret = this._send('', 'binary', finish); @@ -589,7 +572,7 @@ OutgoingMessage.prototype.end = function(data, encoding, callback) { // There is the first message on the outgoing queue, and we've sent // everything to the socket. - debug('outgoing message end.'); + debug(I18N.HTTP_OUTGOING_MESSAGE_END); if (this.output.length === 0 && this.connection && this.connection._httpMessage === this) { @@ -681,4 +664,4 @@ OutgoingMessage.prototype.flushHeaders = function() { OutgoingMessage.prototype.flush = internalUtil.deprecate(function() { this.flushHeaders(); -}, 'OutgoingMessage.flush is deprecated. Use flushHeaders instead.'); +}, I18N(I18N.HTTP_OUTGOING_FLUSH_DEPRECATE)); diff --git a/lib/_http_server.js b/lib/_http_server.js index 7534ceba95e9e1..1171bbd03485d9 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const util = require('util'); const net = require('net'); const EventEmitter = require('events'); @@ -281,7 +282,7 @@ function connectionListener(socket) { } function serverSocketCloseListener() { - debug('server socket close'); + debug(I18N.HTTP_SERVER_DEBUG_SOCKET_CLOSE); // mark this parser as reusable if (this.parser) { freeParser(this.parser, null, this); @@ -290,7 +291,7 @@ function connectionListener(socket) { abortIncoming(); } - debug('SERVER new http connection'); + debug(I18N.HTTP_SERVER_DEBUG_NEW_CONNECTION); httpSocketSetup(socket); @@ -359,26 +360,26 @@ function connectionListener(socket) { function socketOnData(d) { assert(!socket._paused); - debug('SERVER socketOnData %d', d.length); + debug(I18N.HTTP_SERVER_DEBUG_SOCKETONDATA, d.length); var ret = parser.execute(d); onParserExecuteCommon(ret, d); } function onParserExecute(ret, d) { - debug('SERVER socketOnParserExecute %d', ret); + debug(I18N.HTTP_SERVER_DEBUG_SOCKETONPARSEREXECUTE, ret); onParserExecuteCommon(ret, undefined); } function onParserExecuteCommon(ret, d) { if (ret instanceof Error) { - debug('parse error'); + debug(I18N.HTTP_CLIENT_DEBUG_PARSE_ERROR); socketOnError.call(socket, ret); } else if (parser.incoming && parser.incoming.upgrade) { // Upgrade or CONNECT var bytesParsed = ret; var req = parser.incoming; - debug('SERVER upgrade or connect', req.method); + debug(I18N.HTTP_SERVER_DEBUG_UPGRADE_OR_CONNECT, req.method); if (!d) d = parser.getCurrentBuffer(); @@ -393,7 +394,7 @@ function connectionListener(socket) { var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; if (EventEmitter.listenerCount(self, eventName) > 0) { - debug('SERVER have listener for %s', eventName); + debug(I18N.HTTP_SERVER_DEBUG_HAVE_LISTENER, eventName); var bodyHead = d.slice(bytesParsed, d.length); // TODO(isaacs): Need a way to reset a stream to fresh state @@ -408,7 +409,7 @@ function connectionListener(socket) { if (socket._paused && socket.parser) { // onIncoming paused the socket, we should pause the parser as well - debug('pause parser'); + debug(I18N.HTTP_SERVER_DEBUG_PAUSE_PARSER); socket.parser.pause(); } } @@ -418,7 +419,7 @@ function connectionListener(socket) { var ret = parser.finish(); if (ret instanceof Error) { - debug('parse error'); + debug(I18N.HTTP_CLIENT_DEBUG_PARSE_ERROR); socketOnError.call(socket, ret); return; } diff --git a/lib/_linklist.js b/lib/_linklist.js index 08ecbea828b666..7960eddd91590e 100644 --- a/lib/_linklist.js +++ b/lib/_linklist.js @@ -1,6 +1,7 @@ 'use strict'; +const I18N = require('internal/messages'); const msg = require('internal/util').printDeprecationMessage; module.exports = require('internal/linkedlist'); -msg('_linklist module is deprecated. Please use a userland alternative.'); +msg(I18N(I18N.LINKLIST_DEPRECATED)); diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index bdc263d6ef28f4..5b977c0203695e 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -3,11 +3,12 @@ module.exports = Readable; Readable.ReadableState = ReadableState; +const I18N = require('internal/messages'); +const debug = I18N.debuglog('stream'); const EE = require('events'); const Stream = require('stream'); const Buffer = require('buffer').Buffer; const util = require('util'); -const debug = util.debuglog('stream'); var StringDecoder; util.inherits(Readable, Stream); @@ -129,11 +130,11 @@ function readableAddChunk(stream, state, chunk, encoding, addToFront) { onEofChunk(stream, state); } else if (state.objectMode || chunk && chunk.length > 0) { if (state.ended && !addToFront) { - var e = new Error('stream.push() after EOF'); - stream.emit('error', e); + stream.emit('error', + new I18N.Error(I18N.STREAM_READABLE_PUSH_AFTER_END)); } else if (state.endEmitted && addToFront) { - var e = new Error('stream.unshift() after end event'); - stream.emit('error', e); + stream.emit('error', + new I18N.Error(I18N.STREAM_READABLE_UNSHIFT_AFTER_END)); } else { if (state.decoder && !addToFront && !encoding) chunk = state.decoder.write(chunk); @@ -248,7 +249,7 @@ function howMuchToRead(n, state) { // you can override either this method, or the async _read(n) below. Readable.prototype.read = function(n) { - debug('read', n); + debug(I18N.STREAM_READABLE_DEBUG_READ, n); var state = this._readableState; var nOrig = n; @@ -261,7 +262,7 @@ Readable.prototype.read = function(n) { if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { - debug('read: emitReadable', state.length, state.ended); + debug(I18N.STREAM_READABLE_READEMITREADABLE, state.length, state.ended); if (state.length === 0 && state.ended) endReadable(this); else @@ -302,23 +303,23 @@ Readable.prototype.read = function(n) { // if we need a readable event, then we need to do some reading. var doRead = state.needReadable; - debug('need readable', doRead); + debug(I18N.STREAM_READABLE_DEBUG_NEED_READABLE, doRead); // if we currently have less than the highWaterMark, then also read some if (state.length === 0 || state.length - n < state.highWaterMark) { doRead = true; - debug('length less than watermark', doRead); + debug(I18N.STREAM_READABLE_DEBUG_LESS_THAN_WATERMARK, doRead); } // however, if we've ended, then there's no point, and if we're already // reading, then it's unnecessary. if (state.ended || state.reading) { doRead = false; - debug('reading or ended', doRead); + debug(I18N.STREAM_READABLE_DEBUG_READING_OR_ENDED, doRead); } if (doRead) { - debug('do read'); + debug(I18N.STREAM_READABLE_DEBUG_DO_READ); state.reading = true; state.sync = true; // if the length is currently zero, then we *need* a readable event. @@ -369,7 +370,7 @@ function chunkInvalid(state, chunk) { chunk !== null && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); + er = new I18N.TypeError(I18N.STREAM_READABLE_INVALID_CHUNK); } return er; } @@ -397,7 +398,7 @@ function emitReadable(stream) { var state = stream._readableState; state.needReadable = false; if (!state.emittedReadable) { - debug('emitReadable', state.flowing); + debug(I18N.STREAM_READABLE_DEBUG_EMIT_READABLE_ARG, state.flowing); state.emittedReadable = true; if (state.sync) process.nextTick(emitReadable_, stream); @@ -407,7 +408,7 @@ function emitReadable(stream) { } function emitReadable_(stream) { - debug('emit readable'); + debug(I18N.STREAM_READABLE_DEBUG_EMIT_READABLE); stream.emit('readable'); flow(stream); } @@ -430,7 +431,7 @@ function maybeReadMore_(stream, state) { var len = state.length; while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { - debug('maybeReadMore read 0'); + debug(I18N.STREAM_READABLE_DEBUG_MAYBE_READMORE); stream.read(0); if (len === state.length) // didn't get any data, stop spinning. @@ -446,7 +447,7 @@ function maybeReadMore_(stream, state) { // for virtual (non-string, non-buffer) streams, "length" is somewhat // arbitrary, and perhaps not very meaningful. Readable.prototype._read = function(n) { - this.emit('error', new Error('not implemented')); + this.emit('error', new I18N.Error(I18N.NOT_IMPLEMENTED)); }; Readable.prototype.pipe = function(dest, pipeOpts) { @@ -465,7 +466,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) { break; } state.pipesCount += 1; - debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + debug(I18N.STREAM_READABLE_DEBUG_PIPE_COUNT, state.pipesCount, pipeOpts); var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && @@ -479,14 +480,14 @@ Readable.prototype.pipe = function(dest, pipeOpts) { dest.on('unpipe', onunpipe); function onunpipe(readable) { - debug('onunpipe'); + debug(I18N.STREAM_READABLE_DEBUG_ONUNPIPE); if (readable === src) { cleanup(); } } function onend() { - debug('onend'); + debug(I18N.STREAM_READABLE_DEBUG_ONEND); dest.end(); } @@ -499,7 +500,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) { var cleanedUp = false; function cleanup() { - debug('cleanup'); + debug(I18N.STREAM_READABLE_DEBUG_CLEANUP); // cleanup event handlers once the pipe is broken dest.removeListener('close', onclose); dest.removeListener('finish', onfinish); @@ -524,7 +525,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) { src.on('data', ondata); function ondata(chunk) { - debug('ondata'); + debug(I18N.STREAM_READABLE_DEBUG_ONDATA); var ret = dest.write(chunk); if (false === ret) { // If the user unpiped during `dest.write()`, it is possible @@ -534,7 +535,8 @@ Readable.prototype.pipe = function(dest, pipeOpts) { state.pipes[0] === dest && src.listenerCount('data') === 1 && !cleanedUp) { - debug('false write response, pause', src._readableState.awaitDrain); + debug(I18N.STREAM_READABLE_DEBUG_FALSE_WRITE, + src._readableState.awaitDrain); src._readableState.awaitDrain++; } src.pause(); @@ -544,7 +546,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) { // if the dest has an error, then stop piping into it. // however, don't suppress the throwing behavior for this. function onerror(er) { - debug('onerror', er); + debug(I18N.STREAM_READABLE_DEBUG_ONERROR, er); unpipe(); dest.removeListener('error', onerror); if (EE.listenerCount(dest, 'error') === 0) @@ -567,14 +569,14 @@ Readable.prototype.pipe = function(dest, pipeOpts) { } dest.once('close', onclose); function onfinish() { - debug('onfinish'); + debug(I18N.STREAM_READABLE_DEBUG_ONFINISH); dest.removeListener('close', onclose); unpipe(); } dest.once('finish', onfinish); function unpipe() { - debug('unpipe'); + debug(I18N.STREAM_READABLE_DEBUG_UNPIPE); src.unpipe(dest); } @@ -583,7 +585,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) { // start the flow if it hasn't been started already. if (!state.flowing) { - debug('pipe resume'); + debug(I18N.STREAM_READABLE_DEBUG_PIPE_RESUME); src.resume(); } @@ -593,7 +595,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) { function pipeOnDrain(src) { return function() { var state = src._readableState; - debug('pipeOnDrain', state.awaitDrain); + debug(I18N.STREAM_READABLE_DEBUG_PIPEONDRAIN, state.awaitDrain); if (state.awaitDrain) state.awaitDrain--; if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) { @@ -689,7 +691,7 @@ Readable.prototype.on = function(ev, fn) { Readable.prototype.addListener = Readable.prototype.on; function nReadingNextTick(self) { - debug('readable nexttick read 0'); + debug(I18N.STREAM_READABLE_DEBUG_READABLE_NEXTTICK); self.read(0); } @@ -698,7 +700,7 @@ function nReadingNextTick(self) { Readable.prototype.resume = function() { var state = this._readableState; if (!state.flowing) { - debug('resume'); + debug(I18N.STREAM_READABLE_DEBUG_RESUME); state.flowing = true; resume(this, state); } @@ -714,7 +716,7 @@ function resume(stream, state) { function resume_(stream, state) { if (!state.reading) { - debug('resume read 0'); + debug(I18N.STREAM_READABLE_DEBUG_RESUME_READ); stream.read(0); } @@ -726,9 +728,10 @@ function resume_(stream, state) { } Readable.prototype.pause = function() { - debug('call pause flowing=%j', this._readableState.flowing); + debug(I18N.STREAM_READABLE_CALL_PAUSE_FLOWING, + JSON.stringify(this._readableState.flowing)); if (false !== this._readableState.flowing) { - debug('pause'); + debug(I18N.STREAM_READABLE_DEBUG_PAUSE); this._readableState.flowing = false; this.emit('pause'); } @@ -737,7 +740,7 @@ Readable.prototype.pause = function() { function flow(stream) { var state = stream._readableState; - debug('flow', state.flowing); + debug(I18N.STREAM_READABLE_DEBUG_FLOW, state.flowing); if (state.flowing) { do { var chunk = stream.read(); @@ -754,7 +757,7 @@ Readable.prototype.wrap = function(stream) { var self = this; stream.on('end', function() { - debug('wrapped end'); + debug(I18N.STREAM_READABLE_DEBUG_WRAPPED_END); if (state.decoder && !state.ended) { var chunk = state.decoder.end(); if (chunk && chunk.length) @@ -765,7 +768,7 @@ Readable.prototype.wrap = function(stream) { }); stream.on('data', function(chunk) { - debug('wrapped data'); + debug(I18N.STREAM_READABLE_DEBUG_WRAPPED_DATA); if (state.decoder) chunk = state.decoder.write(chunk); @@ -801,7 +804,7 @@ Readable.prototype.wrap = function(stream) { // when we try to consume some more bytes, simply unpause the // underlying stream. self._read = function(n) { - debug('wrapped _read', n); + debug(I18N.STREAM_READABLE_DEBUG_WRAPPED_READ, n); if (paused) { paused = false; stream.resume(); @@ -889,7 +892,7 @@ function endReadable(stream) { // If we get here before consuming all the bytes, then that is a // bug in node. Should never happen. if (state.length > 0) - throw new Error('"endReadable()" called on non-empty stream'); + throw new I18N.Error(I18N.STREAM_READABLE_STREAM_NOT_EMPTY); if (!state.endEmitted) { state.ended = true; diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js index d58f112acfb95a..7f2472a2160222 100644 --- a/lib/_stream_transform.js +++ b/lib/_stream_transform.js @@ -44,6 +44,7 @@ module.exports = Transform; +const I18N = require('internal/messages'); const Duplex = require('_stream_duplex'); const util = require('util'); util.inherits(Transform, Duplex); @@ -67,7 +68,8 @@ function afterTransform(stream, er, data) { var cb = ts.writecb; if (!cb) - return stream.emit('error', new Error('no writecb in Transform class')); + return stream.emit('error', + new I18N.Error(I18N.STREAM_TRANSFORM_NO_WRITECB)); ts.writechunk = null; ts.writecb = null; @@ -138,7 +140,7 @@ Transform.prototype.push = function(chunk, encoding) { // an error, then that'll put the hurt on the whole operation. If you // never call cb(), then you'll never get another chunk. Transform.prototype._transform = function(chunk, encoding, cb) { - throw new Error('Not implemented'); + throw new I18N.Error(I18N.NOT_IMPLEMENTED); }; Transform.prototype._write = function(chunk, encoding, cb) { @@ -182,10 +184,10 @@ function done(stream, er) { var ts = stream._transformState; if (ws.length) - throw new Error('Calling transform done when ws.length != 0'); + throw new I18N.Error(I18N.STREAM_TRANSFORM_DONE_NOT_EMPTY); if (ts.transforming) - throw new Error('Calling transform done when still transforming'); + throw new I18N.Error(I18N.STREAM_TRANSFORM_DONE_STILL_GOING); return stream.push(null); } diff --git a/lib/_stream_wrap.js b/lib/_stream_wrap.js index 7eb3008484b2aa..cf5ef94eee5b4f 100644 --- a/lib/_stream_wrap.js +++ b/lib/_stream_wrap.js @@ -1,12 +1,13 @@ 'use strict'; +const I18N = require('internal/messages'); +const debug = I18N.debuglog('stream_wrap'); const assert = require('assert'); const util = require('util'); const Socket = require('net').Socket; const JSStream = process.binding('js_stream').JSStream; const Buffer = require('buffer').Buffer; const uv = process.binding('uv'); -const debug = util.debuglog('stream_wrap'); function StreamWrap(stream) { const handle = new JSStream(); @@ -17,7 +18,7 @@ function StreamWrap(stream) { const self = this; handle.close = function(cb) { - debug('close'); + debug(I18N.STREAM_WRAP_DEBUG_CLOSE); self.doClose(cb); }; handle.isAlive = function() { @@ -49,16 +50,16 @@ function StreamWrap(stream) { this.pause(); this.removeListener('data', ondata); - self.emit('error', new Error('Stream has StringDecoder')); + self.emit('error', new I18N.Error(I18N.STREAM_WRAP_HAS_STRINGDECODER)); return; } - debug('data', chunk.length); + debug(I18N.STREAM_WRAP_DEBUG_DATA, chunk.length); if (self._handle) self._handle.readBuffer(chunk); }); this.stream.once('end', function onend() { - debug('end'); + debug(I18N.STREAM_WRAP_DEBUG_END); if (self._handle) self._handle.emitEOF(); }); diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 10fcae04f5553e..4ff19b78a2365c 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -7,6 +7,7 @@ module.exports = Writable; Writable.WritableState = WritableState; +const I18N = require('internal/messages'); const util = require('util'); const internalUtil = require('internal/util'); const Stream = require('stream'); @@ -123,8 +124,7 @@ WritableState.prototype.getBuffer = function writableStateGetBuffer() { Object.defineProperty(WritableState.prototype, 'buffer', { get: internalUtil.deprecate(function() { return this.getBuffer(); - }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + - 'instead.') + }, I18N(I18N.STREAM_WRITABLE_WRITABLESTATE_BUFFER_DEPRECATED)) }); function Writable(options) { @@ -151,12 +151,13 @@ function Writable(options) { // Otherwise people can pipe Writable streams, which is just wrong. Writable.prototype.pipe = function() { - this.emit('error', new Error('Cannot pipe, not readable')); + this.emit('error', + new I18N.Error(I18N.STREAM_WRITABLE_CANNOT_PIPE_NOT_READABLE)); }; function writeAfterEnd(stream, cb) { - var er = new Error('write after end'); + var er = new I18N.Error(I18N.WRITE_AFTER_END); // TODO: defer error events consistently everywhere, not just the cb stream.emit('error', er); process.nextTick(cb, er); @@ -175,7 +176,7 @@ function validChunk(stream, state, chunk, cb) { chunk !== null && chunk !== undefined && !state.objectMode) { - var er = new TypeError('Invalid non-string/buffer chunk'); + var er = new I18N.TypeError(I18N.STREAM_READABLE_INVALID_CHUNK); stream.emit('error', er); process.nextTick(cb, er); valid = false; @@ -236,7 +237,7 @@ Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { if (typeof encoding === 'string') encoding = encoding.toLowerCase(); if (!Buffer.isEncoding(encoding)) - throw new TypeError('Unknown encoding: ' + encoding); + throw new I18N.TypeError(I18N.UNKNOWN_ENCODING, encoding); this._writableState.defaultEncoding = encoding; }; @@ -412,7 +413,7 @@ function clearBuffer(stream, state) { } Writable.prototype._write = function(chunk, encoding, cb) { - cb(new Error('not implemented')); + cb(new I18N.Error(I18N.NOT_IMPLEMENTED)); }; Writable.prototype._writev = null; diff --git a/lib/_tls_legacy.js b/lib/_tls_legacy.js index c6497f959ecd3c..5be8db2d94d416 100644 --- a/lib/_tls_legacy.js +++ b/lib/_tls_legacy.js @@ -1,25 +1,29 @@ 'use strict'; +const I18N = require('internal/messages'); +const debug = I18N.debuglog('tls-legacy'); const assert = require('assert'); const EventEmitter = require('events'); const stream = require('stream'); const tls = require('tls'); const util = require('util'); const common = require('_tls_common'); -const debug = util.debuglog('tls-legacy'); const Buffer = require('buffer').Buffer; const Timer = process.binding('timer_wrap').Timer; var Connection = null; try { Connection = process.binding('crypto').Connection; } catch (e) { - throw new Error('Node.js is not compiled with openssl crypto support'); + throw new I18N.Error(I18N.NO_OPENSSL); } function SlabBuffer() { this.create(); } +function debug_label(self) { + return self === self.pair.cleartext ? 'cleartext' : 'encrypted'; +} SlabBuffer.prototype.create = function create() { this.isFull = false; @@ -87,8 +91,8 @@ util.inherits(CryptoStream, stream.Duplex); function onCryptoStreamFinish() { this._finished = true; + debug(I18N.TLS_LEGACY_DEBUG_ONFINISH, debug_label(this)); if (this === this.pair.cleartext) { - debug('cleartext.onfinish'); if (this.pair.ssl) { // Generate close notify // NOTE: first call checks if client has sent us shutdown, @@ -103,8 +107,6 @@ function onCryptoStreamFinish() { if (this.pair.ssl && this.pair.ssl.error) return this.pair.error(); } - } else { - debug('encrypted.onfinish'); } // Try to read just to get sure that we won't miss EOF @@ -121,11 +123,7 @@ function onCryptoStreamFinish() { function onCryptoStreamEnd() { this._ended = true; - if (this === this.pair.cleartext) { - debug('cleartext.onend'); - } else { - debug('encrypted.onend'); - } + debug(I18N.TLS_LEGACY_DEBUG_ONEND, debug_label(this)); } @@ -148,6 +146,8 @@ CryptoStream.prototype._write = function write(data, encoding, cb) { // Black-hole data if (!this.pair.ssl) return cb(null); + const label = debug_label(this); + // When resuming session don't accept any new data. // And do not put too much data into openssl, before writing it from encrypted // side. @@ -157,13 +157,11 @@ CryptoStream.prototype._write = function write(data, encoding, cb) { this._opposite._internallyPendingBytes() < 128 * 1024) { // Write current buffer now var written; - if (this === this.pair.cleartext) { - debug('cleartext.write called with %d bytes', data.length); + debug(I18N.TLS_LEGACY_DEBUG_WRITE, label, data.length); + if (this === this.pair.cleartext) written = this.pair.ssl.clearIn(data, 0, data.length); - } else { - debug('encrypted.write called with %d bytes', data.length); + else written = this.pair.ssl.encIn(data, 0, data.length); - } // Handle and report errors if (this.pair.ssl && this.pair.ssl.error) { @@ -182,11 +180,7 @@ CryptoStream.prototype._write = function write(data, encoding, cb) { // Whole buffer was written if (written === data.length) { - if (this === this.pair.cleartext) { - debug('cleartext.write succeed with ' + written + ' bytes'); - } else { - debug('encrypted.write succeed with ' + written + ' bytes'); - } + debug(I18N.TLS_LEGACY_DEBUG_WRITE_SUCCEED, label, written); // Invoke callback only when all data read from opposite stream if (this._opposite._halfRead) { @@ -204,7 +198,7 @@ CryptoStream.prototype._write = function write(data, encoding, cb) { return; } } else { - debug('cleartext.write queue is full'); + debug(I18N.TLS_LEGACY_DEBUG_CLEARTEXT_WRITE_QUEUE_FULL); // Force SSL_read call to cycle some states/data inside OpenSSL this.pair.cleartext.read(0); @@ -215,11 +209,7 @@ CryptoStream.prototype._write = function write(data, encoding, cb) { this._pendingEncoding = encoding; this._pendingCallback = cb; - if (this === this.pair.cleartext) { - debug('cleartext.write queued with %d bytes', data.length); - } else { - debug('encrypted.write queued with %d bytes', data.length); - } + debug(I18N.TLS_LEGACY_DEBUG_WRITE_QUEUE_BYTES, label, data.length); }; @@ -244,13 +234,13 @@ CryptoStream.prototype._read = function read(size) { if (this._resumingSession || !this._reading) return this.push(''); var out; - if (this === this.pair.cleartext) { - debug('cleartext.read called with %d bytes', size); + const label = debug_label(this); + + debug(I18N.TLS_LEGACY_DEBUG_READ_CALLED, label, size); + if (this === this.pair.cleartext) out = this.pair.ssl.clearOut; - } else { - debug('encrypted.read called with %d bytes', size); + else out = this.pair.ssl.encOut; - } var bytesRead = 0, start = this._buffer.offset, @@ -282,11 +272,7 @@ CryptoStream.prototype._read = function read(size) { assert(bytesRead >= 0); - if (this === this.pair.cleartext) { - debug('cleartext.read succeed with %d bytes', bytesRead); - } else { - debug('encrypted.read succeed with %d bytes', bytesRead); - } + debug(I18N.TLS_LEGACY_DEBUG_READ_SUCCEED, label, bytesRead); // Try writing pending data if (this._pending !== null) this._writePending(); @@ -327,12 +313,7 @@ CryptoStream.prototype._read = function read(size) { // Notify listeners about internal data end if (!halfRead) { - if (this === this.pair.cleartext) { - debug('cleartext.sslOutEnd'); - } else { - debug('encrypted.sslOutEnd'); - } - + debug(I18N.TLS_LEGACY_DEBUG_OUTEND, label); this.emit('sslOutEnd'); } } @@ -392,11 +373,7 @@ CryptoStream.prototype.getCipher = function(err) { CryptoStream.prototype.end = function(chunk, encoding) { - if (this === this.pair.cleartext) { - debug('cleartext.end'); - } else { - debug('encrypted.end'); - } + debug(I18N.TLS_LEGACY_DEBUG_END, debug_label(this)); // Write pending data first if (this._pending !== null) this._writePending(); @@ -408,11 +385,7 @@ CryptoStream.prototype.end = function(chunk, encoding) { CryptoStream.prototype.destroySoon = function(err) { - if (this === this.pair.cleartext) { - debug('cleartext.destroySoon'); - } else { - debug('encrypted.destroySoon'); - } + debug(I18N.TLS_LEGACY_DEBUG_DESTROYSOON, debug_label(this)); if (this.writable) this.end(); @@ -442,11 +415,7 @@ CryptoStream.prototype.destroy = function(err) { this.readable = this.writable = false; // Destroy both ends - if (this === this.pair.cleartext) { - debug('cleartext.destroy'); - } else { - debug('encrypted.destroy'); - } + debug(I18N.TLS_LEGACY_DEBUG_DESTROY, debug_label(this)); this._opposite.destroy(); process.nextTick(destroyNT, this, err ? true : false); @@ -569,7 +538,7 @@ EncryptedStream.prototype._internallyPendingBytes = function() { function onhandshakestart() { - debug('onhandshakestart'); + debug(I18N.TLS_DEBUG_ONHANDSHAKESTART); var self = this; var ssl = self.ssl; @@ -590,7 +559,7 @@ function onhandshakestart() { // state machine and OpenSSL is not re-entrant. We cannot allow the user's // callback to destroy the connection right now, it would crash and burn. setImmediate(function() { - var err = new Error('TLS session renegotiation attack detected'); + var err = new I18N.Error(I18N.TLS_RENEGOTIATION_ATTACK); if (self.cleartext) self.cleartext.emit('error', err); }); } @@ -599,7 +568,7 @@ function onhandshakestart() { function onhandshakedone() { // for future use - debug('onhandshakedone'); + debug(I18N.TLS_DEBUG_ONHANDSHAKEONE); } @@ -797,7 +766,7 @@ SecurePair.prototype.maybeInitFinished = function() { } this._secureEstablished = true; - debug('secure established'); + debug(I18N.TLS_DEBUG_SECURE_ESTABLISHED); this.emit('secure'); } }; @@ -807,7 +776,7 @@ SecurePair.prototype.destroy = function() { if (this._destroying) return; if (!this._doneFlag) { - debug('SecurePair.destroy'); + debug(I18N.TLS_LEGACY_DEBUG_SECUREPAIR_DESTROY); this._destroying = true; // SecurePair should be destroyed only after it's streams @@ -829,7 +798,7 @@ SecurePair.prototype.error = function(returnOnly) { if (!this._secureEstablished) { // Emit ECONNRESET instead of zero return if (!err || err.message === 'ZERO_RETURN') { - var connReset = new Error('socket hang up'); + var connReset = new I18N.Error(I18N.SOCKET_HANG_UP); connReset.code = 'ECONNRESET'; connReset.sslError = err && err.message; diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index d3df48a4c59fc7..a611aacccee2f8 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -1,5 +1,7 @@ 'use strict'; +const I18N = require('internal/messages'); +const debug = I18N.debuglog('tls'); const assert = require('assert'); const crypto = require('crypto'); const net = require('net'); @@ -9,14 +11,13 @@ const common = require('_tls_common'); const StreamWrap = require('_stream_wrap').StreamWrap; const Buffer = require('buffer').Buffer; const Duplex = require('stream').Duplex; -const debug = util.debuglog('tls'); const Timer = process.binding('timer_wrap').Timer; const tls_wrap = process.binding('tls_wrap'); const TCP = process.binding('tcp_wrap').TCP; const Pipe = process.binding('pipe_wrap').Pipe; function onhandshakestart() { - debug('onhandshakestart'); + debug(I18N.TLS_TLS_WRAP_DEBUG_ONHANDSHAKESTART); var self = this; var ssl = self._handle; @@ -37,7 +38,7 @@ function onhandshakestart() { // state machine and OpenSSL is not re-entrant. We cannot allow the user's // callback to destroy the connection right now, it would crash and burn. setImmediate(function() { - var err = new Error('TLS session renegotiation attack detected'); + var err = new I18N.Error(I18N.TLS_RENEGOTIATION_ATTACK); self._emitTLSError(err); }); } @@ -46,7 +47,7 @@ function onhandshakestart() { function onhandshakedone() { // for future use - debug('onhandshakedone'); + debug(I18N.TLS_DEBUG_ONHANDSHAKEONE); this._finishInit(); } @@ -55,14 +56,14 @@ function loadSession(self, hello, cb) { var once = false; function onSession(err, session) { if (once) - return cb(new Error('TLS session callback was called 2 times')); + return cb(new I18N.Error(I18N.TLS_CALLBACK_CALLED_TWICE)); once = true; if (err) return cb(err); if (!self._handle) - return cb(new Error('Socket is closed')); + return cb(new I18N.Error(I18N.SOCKET_CLOSED)); // NOTE: That we have disabled OpenSSL's internal session storage in // `node_crypto.cc` and hence its safe to rely on getting servername only @@ -88,14 +89,14 @@ function loadSNI(self, servername, cb) { var once = false; self._SNICallback(servername, function(err, context) { if (once) - return cb(new Error('TLS SNI callback was called 2 times')); + return cb(new I18N.Error(I18N.TLS_CALLBACK_CALLED_TWICE)); once = true; if (err) return cb(err); if (!self._handle) - return cb(new Error('Socket is closed')); + return cb(new I18N.Error(I18N.SOCKET_CLOSED)); // TODO(indutny): eventually disallow raw `SecureContext` if (context) @@ -127,14 +128,14 @@ function requestOCSP(self, hello, ctx, cb) { var once = false; function onOCSP(err, response) { if (once) - return cb(new Error('TLS OCSP callback was called 2 times')); + return cb(new I18N.Error(I18N.TLS_CALLBACK_CALLED_TWICE)); once = true; if (err) return cb(err); if (!self._handle) - return cb(new Error('Socket is closed')); + return cb(new I18N.Error(I18N.SOCKET_CLOSED)); if (response) self._handle.setOCSPResponse(response); @@ -167,7 +168,7 @@ function oncertcb(info) { return self.destroy(err); if (!self._handle) - return self.destroy(new Error('Socket is closed')); + return self.destroy(new I18N.Error(I18N.SOCKET_CLOSED)); self._handle.certCbDone(); }); @@ -192,7 +193,7 @@ function onnewsession(key, session) { once = true; if (!self._handle) - return self.destroy(new Error('Socket is closed')); + return self.destroy(new I18N.Error(I18N.SOCKET_CLOSED)); self._handle.newSessionDone(); @@ -505,7 +506,8 @@ TLSSocket.prototype.renegotiate = function(options, callback) { } if (!this._handle.renegotiate()) { if (callback) { - process.nextTick(callback, new Error('Failed to renegotiate')); + process.nextTick(callback, + new I18N.Error(I18N.TLS_FAILED_TO_RENEGOTIATE)); } return false; } @@ -531,7 +533,7 @@ TLSSocket.prototype.getTLSTicket = function getTLSTicket() { }; TLSSocket.prototype._handleTimeout = function() { - this._emitTLSError(new Error('TLS handshake timeout')); + this._emitTLSError(new I18N.Error(I18N.TLS_HANDSHAKE_TIMEOUT)); }; TLSSocket.prototype._emitTLSError = function(err) { @@ -574,7 +576,7 @@ TLSSocket.prototype._finishInit = function() { this.servername = this._handle.getServername(); } - debug('secure established'); + debug(I18N.TLS_DEBUG_SECURE_ESTABLISHED); this._secureEstablished = true; if (this._tlsOptions.handshakeTimeout > 0) this.setTimeout(0, this._handleTimeout); @@ -593,7 +595,7 @@ TLSSocket.prototype._start = function() { if (!this._handle) return; - debug('start'); + debug(I18N.TLS_DEBUG_START); if (this._tlsOptions.requestOCSP) this._handle.requestOCSP(); this._handle.start(); @@ -756,7 +758,8 @@ function Server(/* [options], listener */) { var timeout = options.handshakeTimeout || (120 * 1000); if (typeof timeout !== 'number') { - throw new TypeError('"handshakeTimeout" option must be a number'); + throw new I18N.TypeError(I18N.INVALID_OPTION_TYPE, + 'handshakeTimeout', 'number'); } if (self.sessionTimeout) { @@ -807,7 +810,7 @@ function Server(/* [options], listener */) { // Emit ECONNRESET if (!socket._controlReleased && !errorEmitted) { errorEmitted = true; - var connReset = new Error('socket hang up'); + var connReset = new I18N.Error(I18N.NET_SOCKET_HANGUP); connReset.code = 'ECONNRESET'; self.emit('tlsClientError', connReset, socket); } @@ -902,9 +905,8 @@ Server.prototype.setOptions = function(options) { // SNI Contexts High-Level API Server.prototype.addContext = function(servername, context) { - if (!servername) { - throw new Error('"servername" is required parameter for Server.addContext'); - } + if (!servername) + throw new I18N.Error(I18N.REQUIRED_ARG, 'servername'); var re = new RegExp('^' + servername.replace(/([\.^$+?\-\\[\]{}])/g, '\\$1') @@ -1035,8 +1037,8 @@ exports.connect = function(/* [port, host], options, cb */) { // specified in options. var ekeyinfo = socket.getEphemeralKeyInfo(); if (ekeyinfo.type === 'DH' && ekeyinfo.size < options.minDHSize) { - var err = new Error('DH parameter size ' + ekeyinfo.size + - ' is less than ' + options.minDHSize); + var err = new I18N.Error(I18N.TLS_DH_PARAMETER_SIZE_SMALL, + ekeyinfo.size, options.minDHSize); socket.emit('error', err); socket.destroy(); return; @@ -1074,7 +1076,7 @@ exports.connect = function(/* [port, host], options, cb */) { // NOTE: This logic is shared with _http_client.js if (!socket._hadError) { socket._hadError = true; - var error = new Error('socket hang up'); + var error = new I18N.Error(I18N.NET_SOCKET_HANGUP); error.code = 'ECONNRESET'; socket.destroy(error); } diff --git a/lib/assert.js b/lib/assert.js index 4a1406cfca261f..4ab87f793815e0 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -25,6 +25,7 @@ 'use strict'; // UTILITY +const I18N = require('internal/messages'); const compare = process.binding('buffer').compare; const util = require('util'); const Buffer = require('buffer').Buffer; @@ -293,9 +294,8 @@ function expectedException(actual, expected) { function _throws(shouldThrow, block, expected, message) { var actual; - if (typeof block !== 'function') { - throw new TypeError('"block" argument must be a function'); - } + if (typeof block !== 'function') + throw new I18N.TypeError(I18N.FUNCTION_REQUIRED, 'block'); if (typeof expected === 'string') { message = expected; @@ -308,15 +308,15 @@ function _throws(shouldThrow, block, expected, message) { actual = e; } - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); + message = (expected && expected.name ? ` (${expected.name}).` : '.') + + (message ? ` ${message}` : '.'); if (shouldThrow && !actual) { - fail(actual, expected, 'Missing expected exception' + message); + fail(actual, expected, I18N(I18N.ASSERT_MISSING_EXCEPTION, message)); } if (!shouldThrow && expectedException(actual, expected)) { - fail(actual, expected, 'Got unwanted exception' + message); + fail(actual, expected, I18N(I18N.ASSERT_UNWANTED_EXCEPTION, message)); } if ((shouldThrow && actual && expected && diff --git a/lib/buffer.js b/lib/buffer.js index 6600cda0388b8c..0c7daaf84668fd 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -1,6 +1,7 @@ /* eslint-disable require-buffer */ 'use strict'; +const I18N = require('internal/messages'); const binding = process.binding('buffer'); const internalUtil = require('internal/util'); const bindingObj = {}; @@ -47,11 +48,8 @@ function alignPool() { function Buffer(arg, encoding) { // Common case. if (typeof arg === 'number') { - if (typeof encoding === 'string') { - throw new Error( - 'If encoding is specified then the first argument must be a string' - ); - } + if (typeof encoding === 'string') + throw new I18N.Error(I18N.BUFFER_ENCODING_STR); // If less than zero, or NaN. if (arg < 0 || arg !== arg) arg = 0; @@ -142,36 +140,30 @@ function fromObject(obj) { return b; } - if (obj == null) { - throw new TypeError('Must start with number, buffer, array or string'); - } - - if (obj instanceof ArrayBuffer) { - return binding.createFromArrayBuffer(obj); - } - - if (obj.buffer instanceof ArrayBuffer || obj.length) { - var length; - if (typeof obj.length !== 'number' || obj.length !== obj.length) - length = 0; - else - length = obj.length; - var b = allocate(length); - for (var i = 0; i < length; i++) { - b[i] = obj[i] & 255; + if (obj !== null && obj !== undefined) { + if (obj instanceof ArrayBuffer) { + return binding.createFromArrayBuffer(obj); + } else if (obj.buffer instanceof ArrayBuffer || obj.length) { + var length; + if (typeof obj.length !== 'number' || obj.length !== obj.length) + length = 0; + else + length = obj.length; + var b = allocate(length); + for (var i = 0; i < length; i++) { + b[i] = obj[i] & 255; + } + return b; + } else if (obj.type === 'Buffer' && Array.isArray(obj.data)) { + var array = obj.data; + var b = allocate(array.length); + for (var i = 0; i < array.length; i++) + b[i] = array[i] & 255; + return b; } - return b; - } - - if (obj.type === 'Buffer' && Array.isArray(obj.data)) { - var array = obj.data; - var b = allocate(array.length); - for (var i = 0; i < array.length; i++) - b[i] = array[i] & 255; - return b; } - throw new TypeError('Must start with number, buffer, array or string'); + throw new I18N.TypeError(I18N.BUFFER_INVALID_ARG, 'obj'); } @@ -185,7 +177,7 @@ Buffer.isBuffer = function isBuffer(b) { Buffer.compare = function compare(a, b) { if (!(a instanceof Buffer) || !(b instanceof Buffer)) { - throw new TypeError('Arguments must be Buffers'); + throw new I18N.TypeError(I18N.BUFFER_INVALID_ARGS); } if (a === b) { @@ -224,7 +216,7 @@ Buffer.isEncoding = function(encoding) { Buffer.concat = function(list, length) { if (!Array.isArray(list)) - throw new TypeError('"list" argument must be an Array of Buffers'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'list', 'Buffer[]'); if (list.length === 0) return new Buffer(0); @@ -389,7 +381,7 @@ function slowToString(encoding, start, end) { default: if (loweredCase) - throw new TypeError('Unknown encoding: ' + encoding); + throw new I18N.TypeError(I18N.UNKNOWN_ENCODING, encoding); encoding = (encoding + '').toLowerCase(); loweredCase = true; } @@ -404,14 +396,14 @@ Buffer.prototype.toString = function() { var result = slowToString.apply(this, arguments); } if (result === undefined) - throw new Error('"toString()" failed'); + throw new I18N.Error(I18N.BUFFER_TOSTRING_FAILED); return result; }; Buffer.prototype.equals = function equals(b) { if (!(b instanceof Buffer)) - throw new TypeError('Argument must be a Buffer'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'b', 'Buffer'); if (this === b) return true; @@ -429,13 +421,13 @@ Buffer.prototype.inspect = function inspect() { if (this.length > max) str += ' ... '; } - return '<' + this.constructor.name + ' ' + str + '>'; + return `<${this.constructor.name} ${str}>`; }; Buffer.prototype.compare = function compare(b) { if (!(b instanceof Buffer)) - throw new TypeError('Argument must be a Buffer'); + throw new I18N.Error(I18N.INVALID_ARG_TYPE, 'b', 'Buffer'); if (this === b) return 0; @@ -464,7 +456,7 @@ function slowIndexOf(buffer, val, byteOffset, encoding) { default: if (loweredCase) { - throw new TypeError('Unknown encoding: ' + encoding); + throw new I18N.TypeError(I18N.UNKNOWN_ENCODING, encoding); } encoding = ('' + encoding).toLowerCase(); @@ -491,7 +483,7 @@ Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) { return binding.indexOfNumber(this, val, byteOffset); } - throw new TypeError('"val" argument must be string, number or Buffer'); + throw new I18N.TypeError(I18N.BUFFER_INVALID_ARG2, 'val'); }; @@ -505,7 +497,7 @@ Buffer.prototype.fill = function fill(val, start, end) { end = (end === undefined) ? this.length : end >> 0; if (start < 0 || end > this.length) - throw new RangeError('Out of range index'); + throw new I18N.RangeError(I18N.INDEX_OUT_OF_RANGE); if (end <= start) return this; @@ -526,9 +518,7 @@ Buffer.prototype.fill = function fill(val, start, end) { // TODO(trevnorris): fix these checks to follow new standard // write(string, offset = 0, length = buffer.length, encoding = 'utf8') var writeWarned = false; -const writeMsg = 'Buffer.write(string, encoding, offset, length) is ' + - 'deprecated. Use write(string[, offset[, length]]' + - '[, encoding]) instead.'; +const writeMsg = I18N(I18N.BUFFER_WRITE_DEPRECATED); Buffer.prototype.write = function(string, offset, length, encoding) { // Buffer#write(string); if (offset === undefined) { @@ -568,7 +558,7 @@ Buffer.prototype.write = function(string, offset, length, encoding) { length = remaining; if (string.length > 0 && (length < 0 || offset < 0)) - throw new RangeError('Attempt to write outside buffer bounds'); + throw new I18N.RangeError(I18N.OUT_OF_BOUNDS_WRITE); if (!encoding) encoding = 'utf8'; @@ -601,7 +591,7 @@ Buffer.prototype.write = function(string, offset, length, encoding) { default: if (loweredCase) - throw new TypeError('Unknown encoding: ' + encoding); + throw new I18N.TypeError(I18N.UNKNOWN_ENCODING, encoding); encoding = ('' + encoding).toLowerCase(); loweredCase = true; } @@ -628,7 +618,7 @@ Buffer.prototype.slice = function slice(start, end) { function checkOffset(offset, ext, length) { if (offset + ext > length) - throw new RangeError('Index out of range'); + throw new I18N.RangeError(I18N.INDEX_OUT_OF_RANGE); } @@ -836,11 +826,11 @@ Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) { function checkInt(buffer, value, offset, ext, max, min) { if (!(buffer instanceof Buffer)) - throw new TypeError('"buffer" argument must be a Buffer instance'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'buffer', 'Buffer'); if (value > max || value < min) - throw new TypeError('"value" argument is out of bounds'); + throw new I18N.TypeError(I18N.BUFFER_OUTOFBOUNDS_ARG, 'value'); if (offset + ext > buffer.length) - throw new RangeError('Index out of range'); + throw new I18N.RangeError(I18N.INDEX_OUT_OF_RANGE); } diff --git a/lib/child_process.js b/lib/child_process.js index ee73562d24e80f..2bbb0bdfb753d0 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -1,8 +1,9 @@ 'use strict'; +const I18N = require('internal/messages'); +const debug = I18N.debuglog('child_process'); const util = require('util'); const internalUtil = require('internal/util'); -const debug = util.debuglog('child_process'); const constants = require('constants'); const uv = process.binding('uv'); @@ -24,7 +25,7 @@ exports.fork = function(modulePath /*, args, options*/) { args = arguments[1]; options = util._extend({}, arguments[2]); } else if (arguments[1] && typeof arguments[1] !== 'object') { - throw new TypeError('Incorrect value of args option'); + throw new I18N.TypeError(I18N.CHILD_PROCESS_ARG_OPTION); } else { args = []; options = util._extend({}, arguments[1]); @@ -83,7 +84,7 @@ function normalizeExecArgs(command /*, options, callback*/) { if (process.platform === 'win32') { file = process.env.comspec || 'cmd.exe'; - args = ['/s', '/c', '"' + command + '"']; + args = ['/s', '/c', `"${command}"`]; // Make a shallow copy before patching so we don't clobber the user's // options object. options = util._extend({}, options); @@ -145,7 +146,7 @@ exports.execFile = function(file /*, args, options, callback*/) { } if (pos === 1 && arguments.length > 1) { - throw new TypeError('Incorrect value of args option'); + throw new I18N.TypeError(I18N.CHILD_PROCESS_ARG_OPTION); } var child = spawn(file, args, { @@ -210,7 +211,7 @@ exports.execFile = function(file /*, args, options, callback*/) { cmd += ' ' + args.join(' '); if (!ex) { - ex = new Error('Command failed: ' + cmd + '\n' + stderr); + ex = new I18N.Error(I18N.CHILD_PROCESS_COMMAND_FAILED, cmd, stderr); ex.killed = child.killed || killed; ex.code = code < 0 ? uv.errname(code) : code; ex.signal = signal; @@ -263,7 +264,7 @@ exports.execFile = function(file /*, args, options, callback*/) { stdoutLen += chunk.length; if (stdoutLen > options.maxBuffer) { - ex = new Error('stdout maxBuffer exceeded'); + ex = new I18N.Error(I18N.CHILD_PROCESS_MAXBUFFER_EXCEEDED, 'stdout'); kill(); } else { if (!encoding) @@ -282,7 +283,7 @@ exports.execFile = function(file /*, args, options, callback*/) { stderrLen += chunk.length; if (stderrLen > options.maxBuffer) { - ex = new Error('stderr maxBuffer exceeded'); + ex = new I18N.Error(I18N.CHILD_PROCESS_MAXBUFFER_EXCEEDED, 'stderr'); kill(); } else { if (!encoding) @@ -303,8 +304,7 @@ var _deprecatedCustomFds = internalUtil.deprecate(function(options) { options.stdio = options.customFds.map(function(fd) { return fd === -1 ? 'pipe' : fd; }); -}, 'child_process: options.customFds option is deprecated. ' + - 'Use options.stdio instead.'); +}, I18N(I18N.CHILD_PROCESS_CUSTOMFDS_DEPRECATE)); function _convertCustomFds(options) { if (options && options.customFds && !options.stdio) { @@ -320,7 +320,7 @@ function normalizeSpawnArguments(file /*, args, options*/) { options = arguments[2]; } else if (arguments[1] !== undefined && (arguments[1] === null || typeof arguments[1] !== 'object')) { - throw new TypeError('Incorrect value of args option'); + throw new I18N.TypeError(I18N.CHILD_PROCESS_ARG_OPTION); } else { args = []; options = arguments[1]; @@ -329,7 +329,7 @@ function normalizeSpawnArguments(file /*, args, options*/) { if (options === undefined) options = {}; else if (options === null || typeof options !== 'object') - throw new TypeError('"options" argument must be an object'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'options', 'object'); options = util._extend({}, options); args.unshift(file); @@ -357,7 +357,7 @@ var spawn = exports.spawn = function(/*file, args, options*/) { var options = opts.options; var child = new ChildProcess(); - debug('spawn', opts.args, options); + debug(I18N.CHILD_PROCESS_DEBUG_SPAWN, opts.args, options); child.spawn({ file: opts.file, @@ -380,7 +380,7 @@ function lookupSignal(signal) { return signal; if (!(signal in constants)) - throw new Error('Unknown signal: ' + signal); + throw new I18N.Error(I18N.UNKNOWN_SIGNAL, signal); return constants[signal]; } @@ -393,7 +393,7 @@ function spawnSync(/*file, args, options*/) { var i; - debug('spawnSync', opts.args, options); + debug(I18N.CHILD_PROCESS_DEBUG_SPAWNSYNC, opts.args, options); options.file = opts.file; options.args = opts.args; @@ -419,10 +419,8 @@ function spawnSync(/*file, args, options*/) { else if (typeof input === 'string') pipe.input = new Buffer(input, options.encoding); else - throw new TypeError(util.format( - 'stdio[%d] should be Buffer or string not %s', - i, - typeof input)); + throw new I18N.TypeError(I18N.CHILD_PROCESS_INVALID_STDIO, i, + typeof input); } } @@ -440,7 +438,9 @@ function spawnSync(/*file, args, options*/) { result.stderr = result.output && result.output[2]; if (result.error) { - result.error = errnoException(result.error, 'spawnSync ' + opts.file); + result.error = errnoException(result.error, + I18N(I18N.CHILD_PROCESS_SPAWNSYNC, + opts.file)); result.error.path = opts.file; result.error.spawnargs = opts.args.slice(1); } @@ -458,10 +458,9 @@ function checkExecSyncError(ret) { ret.error = null; if (!err) { - var msg = 'Command failed: ' + - (ret.cmd ? ret.cmd : ret.args.join(' ')) + - (ret.stderr ? '\n' + ret.stderr.toString() : ''); - err = new Error(msg); + err = new I18N.Error(I18N.CHILD_PROCESS_COMMAND_FAILED, + ret.cmd ? ret.cmd : ret.args.join(' '), + ret.stderr ? ret.stderr.toString() : ''); } util._extend(err, ret); diff --git a/lib/cluster.js b/lib/cluster.js index 8356fad88a60d0..2c3cbd622cc372 100644 --- a/lib/cluster.js +++ b/lib/cluster.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const EventEmitter = require('events'); const assert = require('assert'); const dgram = require('dgram'); @@ -248,7 +249,7 @@ function masterInit() { initialized = true; schedulingPolicy = cluster.schedulingPolicy; // Freeze policy. assert(schedulingPolicy === SCHED_NONE || schedulingPolicy === SCHED_RR, - 'Bad cluster.schedulingPolicy: ' + schedulingPolicy); + I18N(I18N.CLUSTER_BAD_SCHEDULING, schedulingPolicy)); var hasDebugArg = process.execArgv.some(function(argv) { return /^(--debug|--debug-brk)(=\d+)?$/.test(argv); diff --git a/lib/console.js b/lib/console.js index a0eec4e34878be..3b473ae3a7cd0e 100644 --- a/lib/console.js +++ b/lib/console.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const util = require('util'); function Console(stdout, stderr) { @@ -7,7 +8,7 @@ function Console(stdout, stderr) { return new Console(stdout, stderr); } if (!stdout || typeof stdout.write !== 'function') { - throw new TypeError('Console expects a writable stream instance'); + throw new I18N.TypeError(I18N.CONSOLE_EXPECTS_READABLE); } if (!stderr) { stderr = stdout; @@ -62,9 +63,8 @@ Console.prototype.time = function(label) { Console.prototype.timeEnd = function(label) { var time = this._times.get(label); - if (!time) { - throw new Error('No such label: ' + label); - } + if (!time) + throw new I18N.Error(I18N.CONSOLE_NO_SUCH_LABEL, label); const duration = process.hrtime(time); const ms = duration[0] * 1000 + duration[1] / 1e6; this.log('%s: %sms', label, ms.toFixed(3)); diff --git a/lib/crypto.js b/lib/crypto.js index bed7d7764e3ad5..4d828714db9f4e 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -3,6 +3,8 @@ 'use strict'; +const I18N = require('internal/messages'); + exports.DEFAULT_ENCODING = 'buffer'; try { @@ -12,7 +14,7 @@ try { var getHashes = binding.getHashes; var getCurves = binding.getCurves; } catch (e) { - throw new Error('Node.js is not compiled with openssl crypto support'); + throw new I18N.Error(I18N.NO_OPENSSL); } const Buffer = require('buffer').Buffer; @@ -99,7 +101,8 @@ Hmac.prototype._transform = Hash.prototype._transform; function getDecoder(decoder, encoding) { if (encoding === 'utf-8') encoding = 'utf8'; // Normalize encoding. decoder = decoder || new StringDecoder(encoding); - assert(decoder.encoding === encoding, 'Cannot change encoding'); + assert(decoder.encoding === encoding, + I18N(I18N.CRYPTO_CANNOT_CHANGE_ENCODING)); return decoder; } @@ -272,7 +275,7 @@ Sign.prototype.update = Hash.prototype.update; Sign.prototype.sign = function(options, encoding) { if (!options) - throw new Error('No key provided to sign'); + throw new I18N.Error(I18N.CRYPTO_NO_KEY); var key = options.key || options; var passphrase = options.passphrase || null; @@ -344,7 +347,7 @@ function DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) { if (!(sizeOrKey instanceof Buffer) && typeof sizeOrKey !== 'number' && typeof sizeOrKey !== 'string') - throw new TypeError('First argument should be number, string or Buffer'); + throw new I18N.TypeError(I18N.BUFFER_INVALID_ARG2, 'sizeOrKey'); if (keyEncoding) { if (typeof keyEncoding !== 'string' || @@ -486,7 +489,7 @@ DiffieHellman.prototype.setPrivateKey = function(key, encoding) { function ECDH(curve) { if (typeof curve !== 'string') - throw new TypeError('"curve" argument should be a string'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'curve', 'string'); this._handle = new binding.ECDH(curve); } @@ -519,7 +522,7 @@ ECDH.prototype.getPublicKey = function getPublicKey(encoding, format) { else if (format === 'uncompressed') f = constants.POINT_CONVERSION_UNCOMPRESSED; else - throw new TypeError('Bad format: ' + format); + throw new I18N.TypeError(I18N.CRYPTO_BAD_FORMAT, format); } else { f = constants.POINT_CONVERSION_UNCOMPRESSED; } @@ -542,8 +545,9 @@ exports.pbkdf2 = function(password, digest = undefined; } - if (typeof callback !== 'function') - throw new Error('No callback provided to pbkdf2'); + if (typeof callback !== 'function') { + throw new I18N.Error(I18N.FUNCTION_REQUIRED, 'callback'); + } return pbkdf2(password, salt, iterations, keylen, digest, callback); }; @@ -604,10 +608,10 @@ Certificate.prototype.exportChallenge = function(object, encoding) { exports.setEngine = function setEngine(id, flags) { if (typeof id !== 'string') - throw new TypeError('"id" argument should be a string'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'id', 'string'); if (flags && typeof flags !== 'number') - throw new TypeError('"flags" argument should be a number, if present'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'flags', 'number'); flags = flags >>> 0; // Use provided engine for everything by default @@ -656,10 +660,8 @@ function filterDuplicates(names) { exports.__defineGetter__('createCredentials', internalUtil.deprecate(function() { return require('tls').createSecureContext; - }, 'crypto.createCredentials is deprecated. ' + - 'Use tls.createSecureContext instead.')); + }, I18N(I18N.CRYPTO_CREATECREDENTIALS_DEPRECATED))); exports.__defineGetter__('Credentials', internalUtil.deprecate(function() { return require('tls').SecureContext; -}, 'crypto.Credentials is deprecated. ' + - 'Use tls.createSecureContext instead.')); +}, I18N(I18N.CRYPTO_CREDENTIALS_DEPRECATED))); diff --git a/lib/dgram.js b/lib/dgram.js index b8ffb1f92c5790..e1102dcbc90290 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const assert = require('assert'); const Buffer = require('buffer').Buffer; const util = require('util'); @@ -54,9 +55,9 @@ function newHandle(type) { } if (type == 'unix_dgram') - throw new Error('"unix_dgram" type sockets are not supported any more'); + throw new I18N.Error(I18N.DGRAM_UNIX_DGRAM_NOT_SUPPORTED); - throw new Error('Bad socket type specified. Valid types are: udp4, udp6'); + throw new I18N.Error(I18N.DGRAM_BAD_SOCKET_TYPE); } @@ -140,7 +141,7 @@ Socket.prototype.bind = function(port /*, address, callback*/) { self._healthCheck(); if (this._bindState != BIND_STATE_UNBOUND) - throw new Error('Socket is already bound'); + throw new I18N.Error(I18N.SOCKET_BOUND); this._bindState = BIND_STATE_BINDING; @@ -233,10 +234,10 @@ Socket.prototype.sendto = function(buffer, address, callback) { if (typeof offset !== 'number' || typeof length !== 'number') - throw new Error('Send takes "offset" and "length" as args 2 and 3'); + throw new I18N.Error(I18N.DGRAM_SEND_BAD_ARGUMENTS); if (typeof address !== 'string') - throw new Error(this.type + ' sockets must send to port, address'); + throw new I18N.Error(I18N.DGRAM_MUST_SEND_TO_ADDRESS_PORT, this.type); this.send(buffer, offset, length, port, address, callback); }; @@ -253,28 +254,28 @@ Socket.prototype.send = function(buffer, if (typeof buffer === 'string') buffer = new Buffer(buffer); else if (!(buffer instanceof Buffer)) - throw new TypeError('First argument must be a buffer or string'); + throw new I18N.TypeError(I18N.FIRST_ARGUMENT_STRING_OR_BUFFER); offset = offset | 0; if (offset < 0) - throw new RangeError('Offset should be >= 0'); + throw new I18N.RangeError(I18N.DGRAM_OFFSET_TOO_LOW); if ((length == 0 && offset > buffer.length) || (length > 0 && offset >= buffer.length)) - throw new RangeError('Offset into buffer is too large'); + throw new I18N.RangeError(I18N.DGRAM_OFFSET_TOO_HIGH); // Sending a zero-length datagram is kind of pointless but it _is_ // allowed, hence check that length >= 0 rather than > 0. length = length | 0; if (length < 0) - throw new RangeError('Length should be >= 0'); + throw new I18N.RangeError(I18N.DGRAM_LENGTH_TOO_LOW); if (offset + length > buffer.length) - throw new RangeError('Offset + length beyond buffer length'); + throw new I18N.RangeError(I18N.DGRAM_OFFSET_LENGTH_OVER); port = port | 0; if (port <= 0 || port > 65535) - throw new RangeError('Port should be > 0 and < 65536'); + throw new I18N.RangeError(I18N.PORT_OUT_OF_RANGE); // Normalize callback so it's either a function or undefined but not anything // else. @@ -388,9 +389,8 @@ Socket.prototype.setBroadcast = function(arg) { Socket.prototype.setTTL = function(arg) { - if (typeof arg !== 'number') { - throw new TypeError('Argument must be a number'); - } + if (typeof arg !== 'number') + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'arg', 'number'); var err = this._handle.setTTL(arg); if (err) { @@ -402,9 +402,8 @@ Socket.prototype.setTTL = function(arg) { Socket.prototype.setMulticastTTL = function(arg) { - if (typeof arg !== 'number') { - throw new TypeError('Argument must be a number'); - } + if (typeof arg !== 'number') + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'arg', 'number'); var err = this._handle.setMulticastTTL(arg); if (err) { @@ -429,9 +428,8 @@ Socket.prototype.addMembership = function(multicastAddress, interfaceAddress) { this._healthCheck(); - if (!multicastAddress) { - throw new Error('multicast address must be specified'); - } + if (!multicastAddress) + throw new I18N.Error(I18N.REQUIRED_ARGUMENT, 'multicastAddress'); var err = this._handle.addMembership(multicastAddress, interfaceAddress); if (err) { @@ -444,9 +442,8 @@ Socket.prototype.dropMembership = function(multicastAddress, interfaceAddress) { this._healthCheck(); - if (!multicastAddress) { - throw new Error('multicast address must be specified'); - } + if (!multicastAddress) + throw new I18N.Error(I18N.REQUIRED_ARGUMENT, 'multicastAddress'); var err = this._handle.dropMembership(multicastAddress, interfaceAddress); if (err) { @@ -456,8 +453,8 @@ Socket.prototype.dropMembership = function(multicastAddress, Socket.prototype._healthCheck = function() { - if (!this._handle) - throw new Error('Not running'); // error message from dgram_legacy.js + if (!this._handle) // error message from dgram_legacy.js + throw new I18N.Error(I18N.NOT_RUNNING); }; diff --git a/lib/dns.js b/lib/dns.js index be735f2cfeac24..c4963bf409f9ce 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const net = require('net'); const util = require('util'); @@ -110,13 +111,12 @@ exports.lookup = function lookup(hostname, options, callback) { // Parse arguments if (hostname && typeof hostname !== 'string') { - throw new TypeError('Invalid arguments: ' + - 'hostname must be a string or falsey'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'hostname', 'string'); } else if (typeof options === 'function') { callback = options; family = 0; } else if (typeof callback !== 'function') { - throw new TypeError('Invalid arguments: callback must be passed'); + throw new I18N.TypeError(I18N.FUNCTION_REQUIRED, 'callback'); } else if (options !== null && typeof options === 'object') { hints = options.hints >>> 0; family = options.family >>> 0; @@ -126,14 +126,14 @@ exports.lookup = function lookup(hostname, options, callback) { hints !== exports.ADDRCONFIG && hints !== exports.V4MAPPED && hints !== (exports.ADDRCONFIG | exports.V4MAPPED)) { - throw new TypeError('Invalid argument: hints must use valid flags'); + throw new I18N.TypeError(I18N.DNS_HINTS_VALUE, 'hints'); } } else { family = options >>> 0; } if (family !== 0 && family !== 4 && family !== 6) - throw new TypeError('Invalid argument: family must be 4 or 6'); + throw new I18N.TypeError(I18N.DNS_FAMILY_VALUE, 'family'); callback = makeAsync(callback); @@ -184,10 +184,10 @@ function onlookupservice(err, host, service) { // lookupService(address, port, callback) exports.lookupService = function(host, port, callback) { if (arguments.length !== 3) - throw new Error('Invalid arguments'); + throw new I18N.Error(I18N.DNS_INVALID_ARGUMENTS); if (cares.isIP(host) === 0) - throw new TypeError('"host" argument needs to be a valid IP address'); + throw new I18N.TypeError(I18N.DNS_VALID_ID, 'host'); callback = makeAsync(callback); @@ -218,9 +218,9 @@ function resolver(bindingName) { return function query(name, callback) { if (typeof name !== 'string') { - throw new Error('"name" argument must be a string'); + throw new I18N.Error(I18N.INVALID_ARG_TYPE, 'name', 'string'); } else if (typeof callback !== 'function') { - throw new Error('"callback" argument must be a function'); + throw new I18N.Error(I18N.FUNCTION_REQUIRED, 'callback'); } callback = makeAsync(callback); @@ -259,13 +259,13 @@ exports.resolve = function(hostname, type_, callback_) { resolver = exports.resolve4; callback = type_; } else { - throw new Error('"type" argument must be a string'); + throw new I18N.Error(I18N.INVALID_ARG_TYPE, 'type', 'string'); } if (typeof resolver === 'function') { return resolver(hostname, callback); } else { - throw new Error('Unknown type "' + type_ + '"'); + throw new I18N.Error(I18N.DNS_UNKNOWN_TYPE, type_); } }; @@ -303,7 +303,7 @@ exports.setServers = function(servers) { if (ver) return newSet.push([ver, s]); - throw new Error('IP address is not properly formatted: ' + serv); + throw new I18N.Error(I18N.DNS_MALFORMED_IP, serv); }); var r = cares.setServers(newSet); @@ -313,8 +313,7 @@ exports.setServers = function(servers) { cares.setServers(orig.join(',')); var err = cares.strerror(r); - throw new Error('c-ares failed to set servers: "' + err + - '" [' + servers + ']'); + throw new I18N.Error(I18N.DNS_FAILED_TO_SET_SERVERS, err, servers); } }; diff --git a/lib/events.js b/lib/events.js index d4c6f167ee6fb9..a6121f54e70f73 100644 --- a/lib/events.js +++ b/lib/events.js @@ -3,6 +3,16 @@ var internalUtil; var domain; +var i18N; +function I18N() { + // Messages have to loaded lazily here because the + // Events module is loaded by src/node.js before + // everything else is initialized + if (!i18N) + i18N = require('internal/messages'); + return i18N; +} + function EventEmitter() { EventEmitter.init.call(this); } @@ -42,8 +52,9 @@ EventEmitter.init = function() { // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { + const i18N = I18N(); if (typeof n !== 'number' || n < 0 || isNaN(n)) - throw new TypeError('"n" argument must be a positive number'); + throw new i18N.TypeError(i18N.ARGUMENT_POSITIVE_NUMBER, 'n'); this._maxListeners = n; return this; }; @@ -116,6 +127,7 @@ function emitMany(handler, isFn, self, args) { } EventEmitter.prototype.emit = function emit(type) { + const i18N = I18N(); var er, handler, len, args, i, events, domain; var needDomainExit = false; var doError = (type === 'error'); @@ -133,7 +145,7 @@ EventEmitter.prototype.emit = function emit(type) { er = arguments[1]; if (domain) { if (!er) - er = new Error('Uncaught, unspecified "error" event'); + er = new i18N.Error(i18N.UNCAUGHT_UNSPECIFIED_ERROR); er.domainEmitter = this; er.domain = domain; er.domainThrown = false; @@ -142,7 +154,7 @@ EventEmitter.prototype.emit = function emit(type) { throw er; // Unhandled 'error' event } else { // At least give some kind of context to the user - var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); + var err = new i18N.Error(i18N.UNCAUGHT_UNSPECIFIED_ERROR2, er); err.context = er; throw err; } @@ -190,12 +202,13 @@ EventEmitter.prototype.emit = function emit(type) { }; EventEmitter.prototype.addListener = function addListener(type, listener) { + const i18N = I18N(); var m; var events; var existing; if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); + throw i18N.TypeError(i18N.FUNCTION_REQUIRED, 'listener'); events = this._events; if (!events) { @@ -235,11 +248,8 @@ EventEmitter.prototype.addListener = function addListener(type, listener) { existing.warned = true; if (!internalUtil) internalUtil = require('internal/util'); - - internalUtil.error('warning: possible EventEmitter memory ' + - 'leak detected. %d %s listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - existing.length, type); + internalUtil.error(i18N(i18N.EVENT_MEMORY_LEAK, + existing.length, type)); console.trace(); } } @@ -251,8 +261,9 @@ EventEmitter.prototype.addListener = function addListener(type, listener) { EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function once(type, listener) { + const i18N = I18N(); if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); + throw new i18N.TypeError(i18N.FUNCTION_REQUIRED, 'listener'); var fired = false; @@ -274,10 +285,11 @@ EventEmitter.prototype.once = function once(type, listener) { // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function removeListener(type, listener) { + const i18N = I18N(); var list, events, position, i; if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); + throw new i18N.TypeError(i18N.FUNCTION_REQUIRED, 'listener'); events = this._events; if (!events) diff --git a/lib/fs.js b/lib/fs.js index 54e6b4ac0d2536..4e52fd126e0091 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -3,6 +3,7 @@ 'use strict'; +const I18N = require('internal/messages'); const SlowBuffer = require('buffer').SlowBuffer; const util = require('util'); const pathModule = require('path'); @@ -37,8 +38,7 @@ const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); const errnoException = util._errnoException; function throwOptionsError(options) { - throw new TypeError('Expected options to be either an object or a string, ' + - 'but got ' + typeof options + ' instead'); + throw new I18N.TypeError(I18N.ARGUMENT_STRING_OR_OBJECT, 'options'); } function rethrow() { @@ -75,7 +75,7 @@ function makeCallback(cb) { } if (typeof cb !== 'function') { - throw new TypeError('"callback" argument must be a function'); + throw new I18N.TypeError(I18N.FUNCTION_REQUIRED, 'callback'); } return function() { @@ -85,13 +85,13 @@ function makeCallback(cb) { function assertEncoding(encoding) { if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); + throw new I18N.Error(I18N.UNKNOWN_ENCODING, encoding); } } function nullCheck(path, callback) { if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes'); + var er = new I18N.Error(I18N.PATH_NULL_BYTES, 'path'); er.code = 'ENOENT'; if (typeof callback !== 'function') throw er; @@ -184,7 +184,7 @@ fs.access = function(path, mode, callback) { callback = mode; mode = fs.F_OK; } else if (typeof callback !== 'function') { - throw new TypeError('"callback" argument must be a function'); + throw new I18N.TypeError(I18N.FUNCTION_REQUIRED, 'callback'); } if (!nullCheck(path, callback)) @@ -348,8 +348,7 @@ function readFileAfterStat(err, st) { } if (size > kMaxLength) { - err = new RangeError('File size is greater than possible Buffer: ' + - `0x${kMaxLength.toString(16)} bytes`); + err = new I18N.RangeError(I18N.FS_SIZE_TOO_LARGE, kMaxLength.toString(16)); return context.close(err); } @@ -530,7 +529,7 @@ function stringToFlags(flag) { case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; } - throw new Error('Unknown file open flag: ' + flag); + throw new I18N.Error(I18N.FS_UNKNOWN_FLAG, flag); } // exported but hidden, only used by test/simple/test-fs-open-flags.js @@ -1115,7 +1114,7 @@ function toUnixTimestamp(time) { // convert to 123.456 UNIX timestamp return time.getTime() / 1000; } - throw new Error('Cannot parse time: ' + time); + throw new I18N.Error(I18N.FS_MALFORMED_TIME, time); } // exported for unit tests, not for public consumption @@ -1423,9 +1422,8 @@ fs.watchFile = function(filename, options, listener) { options = defaults; } - if (typeof listener !== 'function') { - throw new Error('"watchFile()" requires a listener function'); - } + if (typeof listener !== 'function') + throw new I18N.Error(I18N.FUNCTION_REQUIRED, 'listener'); stat = statWatchers.get(filename); @@ -1717,7 +1715,7 @@ function ReadStream(path, options) { else if (typeof options === 'string') options = { encoding: options }; else if (options === null || typeof options !== 'object') - throw new TypeError('"options" argument must be a string or an object'); + throw new I18N.TypeError(I18N.ARGUMENT_STRING_OR_OBJECT, 'options'); // a little bit bigger buffer and water marks by default options = Object.create(options); @@ -1738,16 +1736,16 @@ function ReadStream(path, options) { if (this.start !== undefined) { if (typeof this.start !== 'number') { - throw new TypeError('"start" option must be a Number'); + throw new I18N.TypeError(I18N.INVALID_OPTION_TYPE, 'start', 'number'); } if (this.end === undefined) { this.end = Infinity; } else if (typeof this.end !== 'number') { - throw new TypeError('"end" option must be a Number'); + throw new I18N.TypeError(I18N.INVALID_OPTION_TYPE, 'end', 'number'); } if (this.start > this.end) { - throw new Error('"start" option must be <= "end" option'); + throw new I18N.Error(I18N.FS_OPTION_LESS_THAN, 'start', 'end'); } this.pos = this.start; @@ -1888,7 +1886,7 @@ function WriteStream(path, options) { else if (typeof options === 'string') options = { encoding: options }; else if (options === null || typeof options !== 'object') - throw new TypeError('"options" argument must be a string or an object'); + throw new I18N.TypeError(I18N.ARGUMENT_STRING_OR_OBJECT, 'options'); options = Object.create(options); @@ -1906,10 +1904,10 @@ function WriteStream(path, options) { if (this.start !== undefined) { if (typeof this.start !== 'number') { - throw new TypeError('"start" option must be a Number'); + throw new I18N.TypeError(I18N.INVALID_OPTION_TYPE, 'start', 'number'); } if (this.start < 0) { - throw new Error('"start" must be >= zero'); + throw new I18N.Error(I18N.FS_OPTION_MORE_THAN_0, 'start'); } this.pos = this.start; @@ -1950,7 +1948,7 @@ WriteStream.prototype.open = function() { WriteStream.prototype._write = function(data, encoding, cb) { if (!(data instanceof Buffer)) - return this.emit('error', new Error('Invalid data')); + return this.emit('error', new I18N.Error(I18N.FS_INVALID_DATA)); if (typeof this.fd !== 'number') return this.once('open', function() { @@ -2059,7 +2057,7 @@ SyncWriteStream.prototype.write = function(data, arg1, arg2) { } else if (typeof arg1 === 'function') { cb = arg1; } else { - throw new Error('Bad arguments'); + throw new I18N.Error(I18N.BAD_ARGUMENTS); } } assertEncoding(encoding); diff --git a/lib/http.js b/lib/http.js index 64788dd5c07f9f..3d57eed5bc376e 100644 --- a/lib/http.js +++ b/lib/http.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const util = require('util'); const internalUtil = require('internal/util'); const EventEmitter = require('events'); @@ -92,8 +93,9 @@ Client.prototype.request = function(method, path, headers) { return c; }; -exports.Client = internalUtil.deprecate(Client, 'http.Client is deprecated.'); +exports.Client = internalUtil.deprecate(Client, + I18N(I18N.HTTP_CLIENT_DEPRECRATED)); exports.createClient = internalUtil.deprecate(function(port, host) { return new Client(port, host); -}, 'http.createClient is deprecated. Use http.request instead.'); +}, I18N(I18N.HTTP_CREATECLIENT_DEPRECATED)); diff --git a/lib/https.js b/lib/https.js index 7008a79131c663..6398ed531ab10c 100644 --- a/lib/https.js +++ b/lib/https.js @@ -1,11 +1,12 @@ 'use strict'; +const I18N = require('internal/messages'); +const debug = I18N.debuglog('https'); const tls = require('tls'); const url = require('url'); const http = require('http'); const util = require('util'); const inherits = util.inherits; -const debug = util.debuglog('https'); function Server(opts, requestListener) { if (!(this instanceof Server)) return new Server(opts, requestListener); @@ -65,12 +66,12 @@ function createConnection(port, host, options) { options.host = host; } - debug('createConnection', options); + debug(I18N.HTTPS_DEBUG_CREATECONNECTION, options); if (options._agentKey) { const session = this._getSession(options._agentKey); if (session) { - debug('reuse session for %j', options._agentKey); + debug(I18N.HTTPS_REUSE_SESSION, JSON.stringify(options._agentKey)); options = util._extend({ session: session }, options); @@ -156,7 +157,7 @@ Agent.prototype._cacheSession = function _cacheSession(key, session) { // Put new entry if (this._sessionCache.list.length >= this.maxCachedSessions) { const oldKey = this._sessionCache.list.shift(); - debug('evicting %j', oldKey); + debug(I18N.HTTPS_EVICTING, oldKey); delete this._sessionCache.map[oldKey]; } @@ -173,7 +174,7 @@ exports.request = function(options, cb) { if (typeof options === 'string') { options = url.parse(options); if (!options.hostname) { - throw new Error('Unable to determine the domain name'); + throw new I18N.Error(I18N.HTTP_CLIENT_DOMAIN_NAME); } } else { options = util._extend({}, options); diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index 8757a78f05e885..34882071412fbb 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const StringDecoder = require('string_decoder').StringDecoder; const Buffer = require('buffer').Buffer; const EventEmitter = require('events'); @@ -356,9 +357,8 @@ ChildProcess.prototype.kill = function(sig) { signal = constants[sig]; } - if (signal === undefined) { - throw new Error('Unknown signal: ' + sig); - } + if (signal === undefined) + throw new I18N.Error(I18N.UNKNOWN_SIGNAL, sig); if (this._handle) { var err = this._handle.kill(signal); @@ -506,7 +506,7 @@ function setupChannel(target, channel) { if (this.connected) { return this._send(message, handle, false, callback); } - const ex = new Error('channel closed'); + const ex = new I18N.Error(I18N.CHILD_PROCESS_CHANNEL_CLOSED); if (typeof callback === 'function') { process.nextTick(callback, ex); } else { @@ -519,7 +519,7 @@ function setupChannel(target, channel) { assert(this.connected || this._channel); if (message === undefined) - throw new TypeError('"message" argument cannot be undefined'); + throw new I18N.TypeError(I18N.REQUIRED_ARGUMENT, 'message'); // package messages with a handle object if (handle) { @@ -541,7 +541,7 @@ function setupChannel(target, channel) { } else if (handle instanceof UDP) { message.type = 'dgram.Native'; } else { - throw new TypeError('This handle type can\'t be sent'); + throw new I18N.TypeError(I18N.CHILD_PROCESS_BAD_HANDLE_TYPE); } // Queue-up message and handle if we haven't received ACK yet. @@ -628,7 +628,7 @@ function setupChannel(target, channel) { target.disconnect = function() { if (!this.connected) { - this.emit('error', new Error('IPC channel is already disconnected')); + this.emit('error', new I18N.Error(I18N.CHILD_PROCESS_IPC_DISCONNECTED)); return; } @@ -701,11 +701,12 @@ function _validateStdio(stdio, sync) { case 'ignore': stdio = ['ignore', 'ignore', 'ignore']; break; case 'pipe': stdio = ['pipe', 'pipe', 'pipe']; break; case 'inherit': stdio = [0, 1, 2]; break; - default: throw new TypeError('Incorrect value of stdio option: ' + stdio); + default: + throw new I18N.TypeError(I18N.CHILD_PROCESS_INCORRECT_STDIO, stdio); } } else if (!Array.isArray(stdio)) { - throw new TypeError('Incorrect value of stdio option: ' + - util.inspect(stdio)); + throw new I18N.TypeError(I18N.CHILD_PROCESS_INCORRECT_STDIO, + util.inspect(stdio)); } // At least 3 stdio will be created @@ -749,9 +750,9 @@ function _validateStdio(stdio, sync) { // Cleanup previously created pipes cleanup(); if (!sync) - throw new Error('Child process can have only one IPC pipe'); + throw new I18N.Error(I18N.CHILD_PROCESS_ONE_IPC); else - throw new Error('You cannot use IPC with synchronous forks'); + throw new I18N.Error(I18N.CHILD_PROCESS_NOIPC_SYNC); } ipc = new Pipe(true); @@ -786,14 +787,14 @@ function _validateStdio(stdio, sync) { } else if (stdio instanceof Buffer || typeof stdio === 'string') { if (!sync) { cleanup(); - throw new TypeError('Asynchronous forks do not support Buffer input: ' + - util.inspect(stdio)); + throw new I18N.TypeError(I18N.CHILD_PROCESS_BUFFER_NOT_SUPPORTED, + util.inspect(stdio)); } } else { // Cleanup cleanup(); - throw new TypeError('Incorrect value for stdio stream: ' + - util.inspect(stdio)); + throw new I18N.TypeError(I18N.CHILD_PROCESS_INCORRECT_STDIO, + util.inspect(stdio)); } return acc; diff --git a/lib/internal/messages.js b/lib/internal/messages.js new file mode 100644 index 00000000000000..ab179ad1c307b9 --- /dev/null +++ b/lib/internal/messages.js @@ -0,0 +1,182 @@ +'use strict'; + +/** + * Provides a simple internal API useful for externalizing Node.js' own + * output. The messages are defined as string templates compiled into + * the Node binary itself. The format is straightforward: + * + * const I18N = require('internal/messages'); + * + * Message keys are integers defined as constants on the I18N object: + * e.g. I18N.ERR_FOO, I18N.ERR_BAR, etc + * + * Given a hypothetical key ERR_FOO, with a message "Hello {0}", + * + * const I18N = require('internal/messages'); + * console.log(I18N(I18N.ERR_FOO, 'World')); // Prints: Hello World + * + * If a particular message is expected to be used multiple times, the + * special `prepare()` method can be used to create a shortcut function: + * + * const I18N = require('internal/messages'); + * const hello = I18N.prepare(I18N.ERR_FOO); + * console.log(hello('World')); // Prints: Hello World + * + * As a convenience, it is possible to generate Error objects: + * + * const I18N = require('internal/messages'); + * throw new I18N.TypeError('I18N.ERR_FOO, 'World'); + * throw new I18N.Error(I18N.ERR_FOO, 'World'); + * throw new I18N.RangeError(I18N.ERR_FOO, 'World'); + * + * These Error objects will include both the expanded message and the + * string version of the message key in the Error.message. Each will + * include a `.key` property whose value is the string version of the + * message key, and a `.args` property whose values is an array of the + * replacement arguments passed in to generate the message. + * + * Calls to console.log() and console.error() can also be replaced with + * externalized versions: + * + * const I18N = require('internal/messages'); + * I18N.log(I18N.ERR_FOO, 'World'); + * // Prints: `Hello World (ERR_FOO)` to stdout + * I18N.error(I18N.ERR_FOO, 'World'); + * // Prints: `Hello World (ERR_FOO)` to stderr + * + **/ + +const messages = process.binding('messages'); + +function msg(key) { + return messages.messages[key]; +} + +function id(key) { + return messages.keys[key]; +} + +function replacement(msg, values) { + if (values && values.length > 0) + msg = msg.replace(/{(\d)}/g, (_, index) => values[Number(index)]); + return msg; +} + +// I18N(key[, ...args]) +// Returns: string +function message() { + const key = arguments[0]; + const args = []; + for (let n = 1; n < arguments.length; n++) + args.push(arguments[n]); + return replacement(msg(key), args); +} + +// I18N.prepare(key) +// Returns: function([...args]) +message.prepare = function(key) { + const message = msg(key); + return function() { + const args = []; + for (let n = 0; n < arguments.length; n++) + args.push(arguments[n]); + return replacement(message, args); + }; +}; + +class MTypeError extends TypeError { + constructor() { + const key = arguments[0]; + const _id = id(key); + const args = []; + for (let n = 1; n < arguments.length; n++) + args.push(arguments[n]); + super(`${replacement(msg(key), args)} (${_id})`); + Error.captureStackTrace(this, MTypeError); + this.key = _id; + this.args = args; + } +} +class MRangeError extends RangeError { + constructor() { + const key = arguments[0]; + const _id = id(key); + const args = []; + for (let n = 1; n < arguments.length; n++) + args.push(arguments[n]); + super(`${replacement(msg(key), args)} (${_id})`); + Error.captureStackTrace(this, MRangeError); + this.key = _id; + this.args = args; + } +} +class MError extends Error { + constructor() { + const key = arguments[0]; + const _id = id(key); + const args = []; + for (let n = 1; n < arguments.length; n++) + args.push(arguments[n]); + super(`${replacement(msg(key), args)} (${_id})`); + Error.captureStackTrace(this, MError); + this.key = _id; + this.args = args; + } +} + +// throw new I18N.TypeError(key[, ...args]) +message.TypeError = MTypeError; + +// throw new I18N.RangeError(key[, ...args]) +message.RangeError = MRangeError; + +// throw new I18N.Error(key[, ...args]) +message.Error = MError; + +// I18N.log(key[, ... args]) +// Returns: undefined +message.log = function() { + const key = arguments[0]; + const args = []; + for (let n = 1; n < arguments.length; n++) + args.push(arguments[n]); + console.log(`${replacement(msg(key), args)} (${id(key)})`); +}; + +// I18N.error(key[, ... args]) +// Returns: undefined +message.error = function() { + const key = arguments[0]; + const args = []; + for (let n = 1; n < arguments.length; n++) + args.push(arguments[n]); + console.error(`${replacement(msg(key), args)} (${id(key)})`); +}; + +// this is an externalized string aware version of util.debuglog that +// ensures that the string resolution and expansion only happens if +// debug is enabled. +const debugs = {}; +const debugEnviron = process.env.NODE_DEBUG || ''; +message.debuglog = function(set) { + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp(`\\b${set}\\b`, 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + const key = arguments[0]; + const args = []; + for (let n = 1; n < arguments.length; n++) + args.push(arguments[n]); + console.error(`${set} ${pid}: ${replacement(msg(key), args)}`); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + +Object.setPrototypeOf(message, messages); + +module.exports = message; diff --git a/lib/internal/repl.js b/lib/internal/repl.js index e6b41fbdd89b65..73536136f78c06 100644 --- a/lib/internal/repl.js +++ b/lib/internal/repl.js @@ -1,11 +1,12 @@ 'use strict'; +const I18N = require('internal/messages'); +const debug = require('util').debuglog('repl'); const Interface = require('readline').Interface; const REPL = require('repl'); const path = require('path'); const fs = require('fs'); const os = require('os'); -const debug = require('util').debuglog('repl'); module.exports = Object.create(REPL); module.exports.createInternalRepl = createRepl; @@ -68,8 +69,7 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) { try { historyPath = path.join(os.homedir(), '.node_repl_history'); } catch (err) { - repl._writeToOutput('\nError: Could not get the home directory.\n' + - 'REPL session history will not be persisted.\n'); + repl._writeToOutput(`\n${I18N(I18N.REPL_HOME_DIRECTORY)}\n`); repl._refreshLine(); debug(err.stack); @@ -88,8 +88,7 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) { if (err) { // Cannot open history file. // Don't crash, just don't persist history. - repl._writeToOutput('\nError: Could not open history file.\n' + - 'REPL session history will not be persisted.\n'); + repl._writeToOutput(`\n${I18N(I18N.REPL_CANNOT_OPEN_HISTORY)}\n`); repl._refreshLine(); debug(err.stack); @@ -118,15 +117,13 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) { // If pre-v3.0, the user had set NODE_REPL_HISTORY_FILE to // ~/.node_repl_history, warn the user about it and proceed. repl._writeToOutput( - '\nThe old repl history file has the same name and location as ' + - `the new one i.e., ${historyPath} and is empty.\nUsing it as is.\n`); + `\n${I18N(I18N.REPL_HISTORY_SAME_NAME, historyPath)}\n`); repl._refreshLine(); } else if (oldHistoryPath) { // Grab data from the older pre-v3.0 JSON NODE_REPL_HISTORY_FILE format. repl._writeToOutput( - '\nConverting old JSON repl history to line-separated history.\n' + - `The new repl history file can be found at ${historyPath}.\n`); + `\n${I18N(I18N.REPL_CONVERTING_HISTORY, historyPath)}\n`); repl._refreshLine(); try { @@ -138,13 +135,13 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) { if (oldReplJSONHistory) repl.history = JSON.parse(oldReplJSONHistory); if (!Array.isArray(repl.history)) { - throw new Error('Expected array, got ' + typeof repl.history); + throw new I18N.Error(I18N.INVALID_ARG_TYPE, 'repl.history', 'array'); } repl.history = repl.history.slice(0, repl.historySize); } catch (err) { if (err.code !== 'ENOENT') { - return ready( - new Error(`Could not parse history data in ${oldHistoryPath}.`)); + return ready(new I18N.Error(I18N.REPL_CANNOT_PARSE_HISTORY, + oldHistoryPath)); } } } @@ -206,11 +203,7 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) { function _replHistoryMessage() { if (this.history.length === 0) { - this._writeToOutput( - '\nPersistent history support disabled. ' + - 'Set the NODE_REPL_HISTORY environment\nvariable to ' + - 'a valid, user-writable path to enable.\n' - ); + this._writeToOutput(`\n${I18N(I18N.REPL_HISTORY_DISABLED)}\n`); this._refreshLine(); } this._historyPrev = Interface.prototype._historyPrev; diff --git a/lib/internal/socket_list.js b/lib/internal/socket_list.js index 950d632a26360d..cca412c05ad68a 100644 --- a/lib/internal/socket_list.js +++ b/lib/internal/socket_list.js @@ -2,6 +2,7 @@ module.exports = {SocketListSend, SocketListReceive}; +const I18N = require('internal/messages'); const EventEmitter = require('events'); const util = require('util'); @@ -22,7 +23,7 @@ SocketListSend.prototype._request = function(msg, cmd, callback) { function onclose() { self.slave.removeListener('internalMessage', onreply); - callback(new Error('Slave closed before reply')); + callback(new I18N.Error(I18N.SOCKET_LIST_SLAVE_CLOSED)); } function onreply(msg) { diff --git a/lib/internal/v8_prof_polyfill.js b/lib/internal/v8_prof_polyfill.js index 755f8f0d65d1fb..9af672b52e52b6 100644 --- a/lib/internal/v8_prof_polyfill.js +++ b/lib/internal/v8_prof_polyfill.js @@ -26,6 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Node polyfill +const I18N = require('internal/messages'); const fs = require('fs'); const cp = require('child_process'); const os = { @@ -56,7 +57,7 @@ const logFile = arguments[arguments.length - 1]; try { fs.accessSync(logFile); } catch(e) { - console.error('Please provide a valid isolate file as the final argument.'); + I18N.error(I18N.V8_VALID_ISOLATE_FILE); process.exit(1); } const fd = fs.openSync(logFile, 'r'); @@ -89,13 +90,13 @@ function versionCheck() { firstLine = firstLine.split(','); const curVer = process.versions.v8.split('.'); if (firstLine.length !== 6 && firstLine[0] !== 'v8-version') { - console.log('Unable to read v8-version from log file.'); + I18N.log(I18N.V8_UNABLE_TO_READ_VERSION); return; } // Compare major, minor and build; ignore the patch and candidate fields. for (var i = 0; i < 3; i++) { if (curVer[i] !== firstLine[i + 1]) { - console.log('Testing v8 version different from logging version'); + I18N.log(I18N.V8_VERSION_DIFFERENT); return; } } diff --git a/lib/module.js b/lib/module.js index e403c1f73bc190..d77ccf42e767ec 100644 --- a/lib/module.js +++ b/lib/module.js @@ -1,7 +1,7 @@ 'use strict'; const NativeModule = require('native_module'); -const util = require('util'); +const I18N = require('internal/messages'); const internalModule = require('internal/module'); const internalUtil = require('internal/util'); const runInThisContext = require('vm').runInThisContext; @@ -55,7 +55,7 @@ Module.globalPaths = []; Module.wrapper = NativeModule.wrapper; Module.wrap = NativeModule.wrap; -Module._debug = util.debuglog('module'); +Module._debug = I18N.debuglog('module'); // We use this alias for the preprocessor that filters it out const debug = Module._debug; @@ -182,9 +182,7 @@ Module._findPath = function(request, paths) { // Warn once if '.' resolved outside the module dir if (request === '.' && i > 0) { warned = internalUtil.printDeprecationMessage( - 'warning: require(\'.\') resolved outside the package ' + - 'directory. This functionality is deprecated and will be removed ' + - 'soon.', warned); + I18N(I18N.MODULE_REQUIRE_OUTSIDE_WARNING), warned); } Module._pathCache[cacheKey] = filename; @@ -264,8 +262,7 @@ Module._resolveLookupPaths = function(request, parent) { id = './' + id; } - debug('RELATIVE: requested: %s set ID to: %s from %s', request, id, - parent.id); + debug(I18N.MODULE_DEBUG_RELATIVE_REQUESTED, request, id, parent.id); return [id, [path.dirname(parent.filename)]]; }; @@ -280,7 +277,7 @@ Module._resolveLookupPaths = function(request, parent) { // object. Module._load = function(request, parent, isMain) { if (parent) { - debug('Module._load REQUEST %s parent: %s', request, parent.id); + debug(I18N.MODULE_DEBUG_LOAD_REQUEST, request, parent.id); } var filename = Module._resolveFilename(request, parent); @@ -291,7 +288,7 @@ Module._load = function(request, parent, isMain) { } if (NativeModule.nonInternalExists(filename)) { - debug('load native module %s', request); + debug(I18N.MODULE_DEBUG_LOAD_NATIVE, request); return NativeModule.require(filename); } @@ -328,11 +325,12 @@ Module._resolveFilename = function(request, parent) { var paths = resolvedModule[1]; // look up the filename first, since that's the cache key. - debug('looking for %j in %j', id, paths); + debug(I18N.MODULE_DEBUG_LOOKING_FOR, + JSON.stringify(id), JSON.stringify(paths)); var filename = Module._findPath(request, paths); if (!filename) { - var err = new Error("Cannot find module '" + request + "'"); + var err = new I18N.Error(I18N.MODULE_NOT_FOUND, request); err.code = 'MODULE_NOT_FOUND'; throw err; } @@ -342,7 +340,7 @@ Module._resolveFilename = function(request, parent) { // Given a file name, pass it to the proper extension handler. Module.prototype.load = function(filename) { - debug('load %j for module %j', filename, this.id); + debug(I18N.MODULE_DEBUG_LOAD, filename, this.id); assert(!this.loaded); this.filename = filename; @@ -358,8 +356,8 @@ Module.prototype.load = function(filename) { // Loads a module at the given file path. Returns that module's // `exports` property. Module.prototype.require = function(path) { - assert(path, 'missing path'); - assert(typeof path === 'string', 'path must be a string'); + assert(path, I18N(I18N.MODULE_ASSERT_MISSING_PATH)); + assert(typeof path === 'string', I18N(I18N.MODULE_ASSERT_PATH_STRING)); return Module._load(path, this); }; @@ -473,7 +471,7 @@ Module._initPaths = function() { // TODO(bnoordhuis) Unused, remove in the future. Module.requireRepl = internalUtil.deprecate(function() { return NativeModule.require('internal/repl'); -}, 'Module.requireRepl is deprecated.'); +}, I18N(I18N.MODULE_REQUIREREPL_DEPRECATED)); Module._preloadModules = function(requests) { if (!Array.isArray(requests)) diff --git a/lib/net.js b/lib/net.js index 73040b52111f03..a055d1a2839d33 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1,5 +1,7 @@ 'use strict'; +const I18N = require('internal/messages'); +const debug = I18N.debuglog('net'); const EventEmitter = require('events'); const stream = require('stream'); const timers = require('timers'); @@ -29,12 +31,9 @@ function createHandle(fd) { var type = TTYWrap.guessHandleType(fd); if (type === 'PIPE') return new Pipe(); if (type === 'TCP') return new TCP(); - throw new TypeError('Unsupported fd type: ' + type); + throw new I18N.TypeError(I18N.NET_UNSUPPORTED_FD, type); } - -const debug = util.debuglog('net'); - function isPipeName(s) { return typeof s === 'string' && toNumber(s) === false; } @@ -58,7 +57,7 @@ exports.createServer = function(options, connectionListener) { // exports.connect = exports.createConnection = function() { var args = normalizeConnectArgs(arguments); - debug('createConnection', args); + debug(I18N.NET_DEBUG_CREATECONNECTION, args); var s = new Socket(args[0]); return Socket.prototype.connect.apply(s, args); }; @@ -186,17 +185,17 @@ Socket.prototype._unrefTimer = function unrefTimer() { function onSocketFinish() { // If still connecting - defer handling 'finish' until 'connect' will happen if (this._connecting) { - debug('osF: not yet connected'); + debug(I18N.NET_DEBUG_NOTYETCONNECTED); return this.once('connect', onSocketFinish); } - debug('onSocketFinish'); + debug(I18N.NET_DEBUG_ONSOCKETFINISH); if (!this.readable || this._readableState.ended) { - debug('oSF: ended, destroy', this._readableState); + debug(I18N.NET_DEBUG_OSFENDED, this._readableState); return this.destroy(); } - debug('oSF: not ended, call shutdown()'); + debug(I18N.NET_DEBUG_OFSNOTENDED); // otherwise, just shutdown, or destroy() if not possible if (!this._handle || !this._handle.shutdown) @@ -215,15 +214,14 @@ function onSocketFinish() { function afterShutdown(status, handle, req) { var self = handle.owner; - debug('afterShutdown destroyed=%j', self.destroyed, - self._readableState); + debug(I18N.NET_DEBUG_AFTERSHUTDOWN, self.destroyed, self._readableState); // callback may come after call to destroy. if (self.destroyed) return; if (self._readableState.ended) { - debug('readableState ended, destroying'); + debug(I18N.NET_DEBUG_READABLESTATEENDED); self.destroy(); } else { self.once('_socketEnd', self.destroy); @@ -237,7 +235,7 @@ function onSocketEnd() { // XXX Should not have to do as much crap in this function. // ended should already be true, since this is called *after* // the EOF errno and onread has eof'ed - debug('onSocketEnd', this._readableState); + debug(I18N.NET_DEBUG_ONSOCKET_END, this._readableState); this._readableState.ended = true; if (this._readableState.endEmitted) { this.readable = false; @@ -265,7 +263,7 @@ function writeAfterFIN(chunk, encoding, cb) { encoding = null; } - var er = new Error('This socket has been ended by the other party'); + var er = new I18N.Error(I18N.NET_PEER_ENDED); er.code = 'EPIPE'; var self = this; // TODO: defer error events consistently everywhere, not just the cb @@ -289,7 +287,7 @@ Socket.prototype.read = function(n) { Socket.prototype.listen = function() { - debug('socket.listen'); + debug(I18N.NET_DEBUG_SOCKETLISTEN); var self = this; self.on('connection', arguments[0]); listen(self, null, null, null); @@ -314,7 +312,7 @@ Socket.prototype.setTimeout = function(msecs, callback) { Socket.prototype._onTimeout = function() { - debug('_onTimeout'); + debug(I18N.NET_DEBUG_ONTIMEOUT); this.emit('timeout'); }; @@ -380,14 +378,14 @@ Object.defineProperty(Socket.prototype, 'bufferSize', { // Just call handle.readStart until we have enough in the buffer Socket.prototype._read = function(n) { - debug('_read'); + debug(I18N.NET_DEBUG_READ); if (this._connecting || !this._handle) { - debug('_read wait for connection'); + debug(I18N.NET_DEBUG_READWAITFORCON); this.once('connect', () => this._read(n)); } else if (!this._handle.reading) { // not already reading, start the flow - debug('Socket._read readStart'); + debug(I18N.NET_DEBUG_READSTART); this._handle.reading = true; var err = this._handle.readStart(); if (err) @@ -434,7 +432,7 @@ Socket.prototype.destroySoon = function() { Socket.prototype._destroy = function(exception, cb) { - debug('destroy'); + debug(I18N.NET_DEBUG_DESTROY); var self = this; @@ -447,7 +445,7 @@ Socket.prototype._destroy = function(exception, cb) { } if (this.destroyed) { - debug('already destroyed, fire error callbacks'); + debug(I18N.NET_DEBUG_ALREADYDESTROYED); fireErrorCallbacks(); return; } @@ -459,13 +457,13 @@ Socket.prototype._destroy = function(exception, cb) { for (var s = this; s !== null; s = s._parent) timers.unenroll(s); - debug('close'); + debug(I18N.NET_DEBUG_CLOSE); if (this._handle) { if (this !== process.stderr) - debug('close handle'); + debug(I18N.NET_DEBUG_CLOSEHANDLE); var isException = exception ? true : false; this._handle.close(function() { - debug('emit close'); + debug(I18N.NET_DEBUG_EMITCLOSE); self.emit('close', isException); }); this._handle.onread = noop; @@ -481,7 +479,7 @@ Socket.prototype._destroy = function(exception, cb) { if (this.server) { COUNTER_NET_SERVER_CONNECTION_CLOSE(this); - debug('has server'); + debug(I18N.NET_DEBUG_HASSERVER); this.server._connections--; if (this.server._emitCloseIfDrained) { this.server._emitCloseIfDrained(); @@ -491,7 +489,7 @@ Socket.prototype._destroy = function(exception, cb) { Socket.prototype.destroy = function(exception) { - debug('destroy', exception); + debug(I18N.NET_DEBUG_DESTROY_ERR, exception); this._destroy(exception); }; @@ -505,10 +503,10 @@ function onread(nread, buffer) { self._unrefTimer(); - debug('onread', nread); + debug(I18N.NET_DEBUG_ONREAD, nread); if (nread > 0) { - debug('got data'); + debug(I18N.NET_DEBUG_GOTDATA); // read success. // In theory (and in practice) calling readStop right now @@ -524,7 +522,7 @@ function onread(nread, buffer) { if (handle.reading && !ret) { handle.reading = false; - debug('readStop'); + debug(I18N.NET_DEBUG_READSTOP); var err = handle.readStop(); if (err) self._destroy(errnoException(err, 'read')); @@ -535,7 +533,7 @@ function onread(nread, buffer) { // if we didn't get any bytes, that doesn't necessarily mean EOF. // wait for the next one. if (nread === 0) { - debug('not any data, keep waiting'); + debug(I18N.NET_DEBUG_NODATA_KEEPREADING); return; } @@ -544,7 +542,7 @@ function onread(nread, buffer) { return self._destroy(errnoException(nread, 'read')); } - debug('EOF'); + debug(I18N.NET_DEBUG_EOF); if (self._readableState.length === 0) { self.readable = false; @@ -614,7 +612,7 @@ Socket.prototype.__defineGetter__('localPort', function() { Socket.prototype.write = function(chunk, encoding, cb) { if (typeof chunk !== 'string' && !(chunk instanceof Buffer)) - throw new TypeError('Invalid data'); + throw new I18N.TypeError(I18N.FS_INVALID_DATA); return stream.Duplex.prototype.write.apply(this, arguments); }; @@ -637,7 +635,7 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) { this._unrefTimer(); if (!this._handle) { - this._destroy(new Error('This socket is closed'), cb); + this._destroy(new I18N.Error(I18N.SOCKET_CLOSED), cb); return false; } @@ -751,17 +749,17 @@ Socket.prototype.__defineGetter__('bytesWritten', function() { function afterWrite(status, handle, req, err) { var self = handle.owner; if (self !== process.stderr && self !== process.stdout) - debug('afterWrite', status); + debug(I18N.NET_DEBUG_AFTERWRITE, status); // callback may come after call to destroy. if (self.destroyed) { - debug('afterWrite destroyed'); + debug(I18N.NET_DEBUG_AFTERWRITE_DESTROYED); return; } if (status < 0) { var ex = exceptionWithHostPort(status, 'write', req.address, req.port); - debug('write failure', ex); + debug(I18N.NET_DEBUG_WRITEFAILURE, ex); self._destroy(ex, req.cb); return; } @@ -769,7 +767,7 @@ function afterWrite(status, handle, req, err) { self._unrefTimer(); if (self !== process.stderr && self !== process.stdout) - debug('afterWrite call cb'); + debug(I18N.NET_DEBUG_AFTERWRITECB); if (req.cb) req.cb.call(self); @@ -794,13 +792,12 @@ function connect(self, address, port, addressType, localAddress, localPort) { localAddress = localAddress || '::'; bind = self._handle.bind6; } else { - self._destroy(new TypeError('Invalid addressType: ' + addressType)); + self._destroy(new I18N.TypeError(I18N.NET_INVALID_ADDRESS_TYPE, + addressType)); return; } - debug('binding to localAddress: %s and localPort: %d', - localAddress, - localPort); + debug(I18N.NET_DEBUG_BINDING, localAddress, localPort); bind = bind.bind(self._handle); err = bind(localAddress, localPort); @@ -883,7 +880,7 @@ Socket.prototype.connect = function(options, cb) { var self = this; var pipe = !!options.path; - debug('pipe', pipe, options.path); + debug(I18N.NET_DEBUG_PIPE, pipe, options.path); if (!this._handle) { this._handle = pipe ? new Pipe() : new TCP(); @@ -917,18 +914,16 @@ function lookupAndConnect(self, options) { var localPort = options.localPort; if (localAddress && !exports.isIP(localAddress)) - throw new TypeError('"localAddress" option must be a valid IP: ' + - localAddress); + throw new I18N.TypeError(I18N.DNS_VALID_ID, 'localAddress'); if (localPort && typeof localPort !== 'number') - throw new TypeError('"localPort" option should be a number: ' + localPort); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'localPort', 'number'); if (typeof port !== 'undefined') { if (typeof port !== 'number' && typeof port !== 'string') - throw new TypeError('"port" option should be a number or string: ' + - port); + throw new I18N.TypeError(I18N.ARGUMENT_STRING_OR_NUMBER, 'port'); if (!isLegalPort(port)) - throw new RangeError('"port" option should be >= 0 and < 65536: ' + port); + throw new I18N.RangeError(I18N.PORT_OUT_OF_RANGE, 'port'); } port |= 0; @@ -944,7 +939,7 @@ function lookupAndConnect(self, options) { } if (options.lookup && typeof options.lookup !== 'function') - throw new TypeError('"lookup" option should be a function'); + throw new I18N.TypeError(I18N.FUNCTION_REQUIRED, 'lookup'); var dnsopts = { family: options.family, @@ -962,8 +957,8 @@ function lookupAndConnect(self, options) { dnsopts.hints |= dns.V4MAPPED; } - debug('connect: find host ' + host); - debug('connect: dns options', dnsopts); + debug(I18N.NET_DEBUG_CONNECT_FINDHOST, host); + debug(I18N.NET_DEBUG_CONNECT_DNSOPTS, dnsopts); self._host = host; var lookup = options.lookup || dns.lookup; lookup(host, dnsopts, function(err, ip, addressType) { @@ -1038,7 +1033,7 @@ function afterConnect(status, handle, req, readable, writable) { // TODO(indutny): assert that the handle is actually an ancestor of old one handle = self._handle; - debug('afterConnect'); + debug(I18N.NET_DEBUG_AFTERCONNECT); assert.ok(self._connecting); self._connecting = false; @@ -1105,11 +1100,10 @@ function Server(options, connectionListener) { return null; } return self._connections; - }, 'Server.connections property is deprecated. ' + - 'Use Server.getConnections method instead.'), + }, I18N(I18N.NET_SERVER_CONNECTIONS_DEPRECATED)), set: internalUtil.deprecate(function(val) { return (self._connections = val); - }, 'Server.connections property is deprecated.'), + }, I18N(I18N.NET_SERVER_CONNECTIONS_DEPRECATED_SET)), configurable: true, enumerable: false }); @@ -1147,7 +1141,7 @@ var createServerHandle = exports._createServerHandle = } catch (e) { // Not a fd we can listen on. This will trigger an error. - debug('listen invalid fd=' + fd + ': ' + e.message); + debug(I18N.NET_DEBUG_INVALIDFD, fd, e.message); return uv.UV_EINVAL; } handle.open(fd); @@ -1168,7 +1162,7 @@ var createServerHandle = exports._createServerHandle = } if (address || port || isTCP) { - debug('bind to ' + (address || 'anycast')); + debug(I18N.NET_DEBUG_BINDTO, (address || 'anycast')); if (!address) { // Try binding to ipv6 first err = handle.bind6('::', port); @@ -1194,15 +1188,15 @@ var createServerHandle = exports._createServerHandle = Server.prototype._listen2 = function(address, port, addressType, backlog, fd) { - debug('listen2', address, port, addressType, backlog, fd); + debug(I18N.NET_DEBUG_LISTEN2, address, port, addressType, backlog, fd); var self = this; // If there is not yet a handle, we need to create one and bind. // In the case of a server sent via IPC, we don't need to do this. if (self._handle) { - debug('_listen2: have a handle already'); + debug(I18N.NET_DEBUG_LISTEN2_HAVE_HANDLE); } else { - debug('_listen2: create a handle'); + debug(I18N.NET_DEBUG_LISTEN2_CREATE_HANDLE); var rval = null; @@ -1347,8 +1341,7 @@ Server.prototype.listen = function() { // Undefined is interpreted as zero (random port) for consistency // with net.connect(). if (typeof h.port !== 'undefined' && !isLegalPort(h.port)) - throw new RangeError('"port" option should be >= 0 and < 65536: ' + - h.port); + throw new I18N.RangeError(I18N.PORT_OUT_OF_RANGE, 'port'); if (h.host) listenAfterLookup(h.port | 0, h.host, backlog, h.exclusive); else @@ -1357,7 +1350,7 @@ Server.prototype.listen = function() { var pipeName = self._pipeName = h.path; listen(self, pipeName, -1, -1, backlog, undefined, h.exclusive); } else { - throw new Error('Invalid listen argument: ' + h); + throw new I18N.Error(I18N.NET_INVALID_LISTENER_ARG, h); } } } else if (isPipeName(arguments[0])) { @@ -1407,7 +1400,7 @@ function onconnection(err, clientHandle) { var handle = this; var self = handle.owner; - debug('onconnection'); + debug(I18N.NET_DEBUG_ONCONNECTION); if (err) { self.emit('error', errnoException(err, 'accept')); @@ -1477,7 +1470,7 @@ Server.prototype.close = function(cb) { if (typeof cb === 'function') { if (!this._handle) { this.once('close', function() { - cb(new Error('Not running')); + cb(new I18N.Error(I18N.NOT_RUNNING)); }); } else { this.once('close', cb); @@ -1509,12 +1502,13 @@ Server.prototype.close = function(cb) { }; Server.prototype._emitCloseIfDrained = function() { - debug('SERVER _emitCloseIfDrained'); + debug(I18N.NET_DEBUG_SERVER_EMITCLOSEIFDRAINED); var self = this; if (self._handle || self._connections) { - debug('SERVER handle? %j connections? %d', - !!self._handle, self._connections); + debug(I18N.NET_DEBUG_SERVER_HANDLE, + JSON.stringify(!!self._handle), + JSON.stringify(self._connections)); return; } @@ -1523,14 +1517,14 @@ Server.prototype._emitCloseIfDrained = function() { function emitCloseNT(self) { - debug('SERVER: emit close'); + debug(I18N.NET_DEBUG_SERVER_EMITCLOSE); self.emit('close'); } Server.prototype.listenFD = internalUtil.deprecate(function(fd, type) { return this.listen({ fd: fd }); -}, 'Server.listenFD is deprecated. Use Server.listen({fd: }) instead.'); +}, I18N(I18N.NET_SERVER_LISTENFD_DEPRECATED)); Server.prototype._setupSlave = function(socketList) { this._usingSlaves = true; diff --git a/lib/os.js b/lib/os.js index ddf7cee9d48791..be23f3efcf5303 100644 --- a/lib/os.js +++ b/lib/os.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const binding = process.binding('os'); const internalUtil = require('internal/util'); const isWindows = process.platform === 'win32'; @@ -48,8 +49,7 @@ exports.tmpDir = exports.tmpdir; exports.getNetworkInterfaces = internalUtil.deprecate(function() { return exports.networkInterfaces(); -}, 'os.getNetworkInterfaces is deprecated. ' + - 'Use os.networkInterfaces instead.'); +}, I18N(I18N.OS_GETNETWORKINTERFACES_DEPRECATED)); exports.EOL = isWindows ? '\r\n' : '\n'; diff --git a/lib/path.js b/lib/path.js index 0a2c0d6bceb0ec..a687774e55b5d2 100644 --- a/lib/path.js +++ b/lib/path.js @@ -1,13 +1,11 @@ 'use strict'; -const util = require('util'); +const I18N = require('internal/messages'); const isWindows = process.platform === 'win32'; function assertPath(path) { - if (typeof path !== 'string') { - throw new TypeError('Path must be a string. Received ' + - util.inspect(path)); - } + if (typeof path !== 'string') + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'path', 'string'); } // resolves . and .. elements in a path array with directory names there @@ -338,7 +336,7 @@ win32.dirname = function(path) { win32.basename = function(path, ext) { if (ext !== undefined && typeof ext !== 'string') - throw new TypeError('"ext" argument must be a string'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'ext', 'string'); var f = win32SplitPath(path)[2]; // TODO: make this comparison case-insensitive on windows? @@ -355,11 +353,8 @@ win32.extname = function(path) { win32.format = function(pathObject) { - if (pathObject === null || typeof pathObject !== 'object') { - throw new TypeError( - 'Parameter "pathObject" must be an object, not ' + typeof pathObject - ); - } + if (pathObject === null || typeof pathObject !== 'object') + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'pathObject', 'object'); var dir = pathObject.dir || pathObject.root; var base = pathObject.base || @@ -539,7 +534,7 @@ posix.dirname = function(path) { posix.basename = function(path, ext) { if (ext !== undefined && typeof ext !== 'string') - throw new TypeError('"ext" argument must be a string'); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'ext', 'string'); var f = posixSplitPath(path)[2]; @@ -556,11 +551,8 @@ posix.extname = function(path) { posix.format = function(pathObject) { - if (pathObject === null || typeof pathObject !== 'object') { - throw new TypeError( - 'Parameter "pathObject" must be an object, not ' + typeof pathObject - ); - } + if (pathObject === null || typeof pathObject !== 'object') + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'pathObject', 'object'); var dir = pathObject.dir || pathObject.root; var base = pathObject.base || diff --git a/lib/punycode.js b/lib/punycode.js index 51aa75132937d5..3782a0f3416217 100644 --- a/lib/punycode.js +++ b/lib/punycode.js @@ -1,6 +1,8 @@ /*! https://mths.be/punycode v1.3.2 by @mathias */ ;(function(root) { + const I18N = require('internal/messages'); + /** Detect free variables */ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; @@ -42,9 +44,9 @@ /** Error messages */ errors = { - 'overflow': 'Overflow: input needs wider integers to process', - 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', - 'invalid-input': 'Invalid input' + 'overflow': I18N.PUNYCODE_OVERFLOW, + 'not-basic': I18N.PUNYCODE_NOTBASIC, + 'invalid-input': I18N.PUNYCODE_INVALIDINPUT }, /** Convenience shortcuts */ @@ -64,7 +66,7 @@ * @returns {Error} Throws a `RangeError` with the applicable error message. */ function error(type) { - throw new RangeError(errors[type]); + throw new RangeError(I18N(errors[type])); } /** diff --git a/lib/readline.js b/lib/readline.js index adfb305fb0baa8..a823e2c154349f 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -8,6 +8,7 @@ const kHistorySize = 30; +const I18N = require('internal/messages'); const util = require('util'); const internalUtil = require('internal/util'); const inherits = util.inherits; @@ -54,14 +55,13 @@ function Interface(input, output, completer, terminal) { } historySize = historySize || kHistorySize; - if (completer && typeof completer !== 'function') { - throw new TypeError('Argument "completer" must be a function'); - } + if (completer && typeof completer !== 'function') + throw new I18N.TypeError(I18N.FUNCTION_REQUIRED, 'completer'); if (typeof historySize !== 'number' || isNaN(historySize) || historySize < 0) { - throw new TypeError('Argument "historySize" must be a positive number'); + throw new I18N.TypeError(I18N.ARGUMENT_POSITIVE_NUMBER, 'historySize'); } // backwards compat; check the isTTY prop of the output stream @@ -218,7 +218,7 @@ Interface.prototype._onLine = function(line) { Interface.prototype._writeToOutput = function _writeToOutput(stringToWrite) { if (typeof stringToWrite !== 'string') - throw new TypeError('"stringToWrite" argument must be a string'); + throw I18N.TypeErrir(I18N.INVALID_ARG_TYPE, 'stringToWrite', 'string'); if (this.output !== null && this.output !== undefined) this.output.write(stringToWrite); @@ -965,7 +965,7 @@ function cursorTo(stream, x, y) { return; if (typeof x !== 'number') - throw new Error('Can\'t set cursor row without also setting it\'s column'); + throw new I18N.Error(I18N.READLINE_CANNOT_SET_COL); if (typeof y !== 'number') { stream.write('\x1b[' + (x + 1) + 'G'); @@ -1055,18 +1055,17 @@ function codePointAt(str, index) { return code; } exports.codePointAt = internalUtil.deprecate(codePointAt, - 'readline.codePointAt is deprecated. ' + - 'Use String.prototype.codePointAt instead.'); + I18N(I18N.READLINE_CODEPOINT_DEPRECATED)); exports.getStringWidth = internalUtil.deprecate(getStringWidth, - 'getStringWidth is deprecated and will be removed.'); + I18N(I18N.READLINE_GETSTRINGWIDTH_DEPRECATED)); exports.isFullWidthCodePoint = internalUtil.deprecate(isFullWidthCodePoint, - 'isFullWidthCodePoint is deprecated and will be removed.'); + I18N(I18N.READLINE_ISFULLWIDTHCODEPOINT_DEPRECATED)); exports.stripVTControlCharacters = internalUtil.deprecate( stripVTControlCharacters, - 'stripVTControlCharacters is deprecated and will be removed.'); + I18N(I18N.READLINE_STRIPVTCONTROLCHARACTERS_DEPRECATED)); diff --git a/lib/repl.js b/lib/repl.js index f80555dba41afc..8c58ca78054f85 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -21,6 +21,8 @@ 'use strict'; +const I18N = require('internal/messages'); +const debug = I18N.debuglog('repl'); const internalModule = require('internal/module'); const internalUtil = require('internal/util'); const util = require('util'); @@ -33,7 +35,6 @@ const Interface = require('readline').Interface; const Console = require('console').Console; const Module = require('module'); const domain = require('domain'); -const debug = util.debuglog('repl'); const parentModule = module; const replMap = new WeakMap(); @@ -70,8 +71,7 @@ exports._builtinLibs = ['assert', 'buffer', 'child_process', 'cluster', 'string_decoder', 'tls', 'tty', 'url', 'util', 'v8', 'vm', 'zlib']; -const BLOCK_SCOPED_ERROR = 'Block-scoped declarations (let, ' + - 'const, function, class) not yet supported outside strict mode'; +const BLOCK_SCOPED_ERROR = I18N(I18N.REPL_BLOCK_SCOPED); class LineParser { @@ -185,7 +185,7 @@ function REPLServer(prompt, dom = options.domain; replMode = options.replMode; } else if (typeof prompt !== 'string') { - throw new Error('An options Object, or a prompt String are required'); + throw new I18N.Error(I18N.REPL_OPTIONS_OR_PROMPT_REQUIRED); } else { options = {}; } @@ -227,7 +227,7 @@ function REPLServer(prompt, displayErrors: false }); } catch (e) { - debug('parse error %j', code, e); + debug(I18N.REPL_DEBUG_PARSE_ERROR, JSON.stringify(code), e); if (self.replMode === exports.REPL_MODE_MAGIC && e.message === BLOCK_SCOPED_ERROR && !retry) { @@ -256,7 +256,7 @@ function REPLServer(prompt, } catch (e) { err = e; if (err && process.domain) { - debug('not recoverable, send to domain'); + debug(I18N.REPL_DEBUG_NOT_RECOVERABLE); process.domain.emit('error', err); process.domain.exit(); return; @@ -276,7 +276,7 @@ function REPLServer(prompt, self.eval = self._domain.bind(eval_); self._domain.on('error', function(e) { - debug('domain error'); + debug(I18N.REPL_DEBUG_DOMAIN_ERROR); const top = replMap.get(self); internalUtil.decorateErrorStack(e); top.outputStream.write((e.stack || e) + '\n'); @@ -360,7 +360,7 @@ function REPLServer(prompt, sawSIGINT = false; return; } - self.output.write('(To exit, press ^C again or type .exit)\n'); + self.output.write(`${I18N(I18N.REPL_EXIT)}\n`); sawSIGINT = true; } else { sawSIGINT = false; @@ -373,7 +373,7 @@ function REPLServer(prompt, }); self.on('line', function(cmd) { - debug('line %j', cmd); + debug(I18N.REPL_DEBUG_LINE, JSON.stringify(cmd)); sawSIGINT = false; var skipCatchall = false; @@ -393,7 +393,7 @@ function REPLServer(prompt, if (self.parseREPLKeyword(keyword, rest) === true) { return; } else if (!self.bufferedCommand) { - self.outputStream.write('Invalid REPL keyword\n'); + self.outputStream.write(`${I18N(I18N.REPL_INVALID_KEYWORD)}\n`); skipCatchall = true; } } @@ -413,20 +413,18 @@ function REPLServer(prompt, evalCmd = evalCmd + '\n'; } - debug('eval %j', evalCmd); + debug(I18N.REPL_DEBUG_EVAL, JSON.stringify(evalCmd)); self.eval(evalCmd, self.context, 'repl', finish); } else { finish(null); } function finish(e, ret) { - debug('finish', e, ret); + debug(I18N.REPL_DEBUG_FINISH, e, ret); self.memory(cmd); if (e && !self.bufferedCommand && cmd.trim().match(/^npm /)) { - self.outputStream.write('npm should be run outside of the ' + - 'node repl, in your normal shell.\n' + - '(Press Control-D to exit.)\n'); + self.outputStream.write(`${I18N(I18N.REPL_NPM_OUTSIDE)}\n`); self.lineParser.reset(); self.bufferedCommand = ''; self.displayPrompt(); @@ -907,7 +905,7 @@ REPLServer.prototype.defineCommand = function(keyword, cmd) { if (typeof cmd === 'function') { cmd = {action: cmd}; } else if (typeof cmd.action !== 'function') { - throw new Error('Bad argument, "action" command must be a function'); + throw new I18N.Error(I18N.FUNCTION_REQUIRED, 'action'); } this.commands[keyword] = cmd; }; @@ -1010,7 +1008,7 @@ function addStandardGlobals(completionGroups, filter) { function defineDefaultCommands(repl) { repl.defineCommand('break', { - help: 'Sometimes you get stuck, this gets you out', + help: I18N(I18N.REPL_COMMAND_BREAK), action: function() { this.lineParser.reset(); this.bufferedCommand = ''; @@ -1020,9 +1018,9 @@ function defineDefaultCommands(repl) { var clearMessage; if (repl.useGlobal) { - clearMessage = 'Alias for .break'; + clearMessage = I18N(I18N.REPL_COMMAND_CLEAR_GLOBAL); } else { - clearMessage = 'Break, and also clear the local context'; + clearMessage = I18N(I18N.REPL_COMMAND_CLEAR); } repl.defineCommand('clear', { help: clearMessage, @@ -1030,7 +1028,7 @@ function defineDefaultCommands(repl) { this.lineParser.reset(); this.bufferedCommand = ''; if (!this.useGlobal) { - this.outputStream.write('Clearing context...\n'); + this.outputStream.write(`${I18N(I18N.REPL_COMMAND_CLEAR_MSG)}\n`); this.resetContext(); } this.displayPrompt(); @@ -1038,14 +1036,14 @@ function defineDefaultCommands(repl) { }); repl.defineCommand('exit', { - help: 'Exit the repl', + help: I18N(I18N.REPL_COMMAND_EXIT), action: function() { this.close(); } }); repl.defineCommand('help', { - help: 'Show repl options', + help: I18N(I18N.REPL_COMMAND_HELP), action: function() { var self = this; Object.keys(this.commands).sort().forEach(function(name) { @@ -1057,20 +1055,22 @@ function defineDefaultCommands(repl) { }); repl.defineCommand('save', { - help: 'Save all evaluated commands in this REPL session to a file', + help: I18N(I18N.REPL_COMMAND_SAVE), action: function(file) { try { fs.writeFileSync(file, this.lines.join('\n') + '\n'); - this.outputStream.write('Session saved to:' + file + '\n'); + this.outputStream.write( + `${I18N(I18N.REPL_COMMAND_SESSION_SAVED, file)}\n`); } catch (e) { - this.outputStream.write('Failed to save:' + file + '\n'); + this.outputStream.write( + `${I18N(I18N.REPL_COMMAND_SAVE_FAILED, file)}\n`); } this.displayPrompt(); } }); repl.defineCommand('load', { - help: 'Load JS from a file into the REPL session', + help: I18N(I18N.REPL_COMMAND_LOAD), action: function(file) { try { var stats = fs.statSync(file); @@ -1085,11 +1085,12 @@ function defineDefaultCommands(repl) { } }); } else { - this.outputStream.write('Failed to load:' + file + - ' is not a valid file\n'); + this.outputStream.write( + `${I18N(I18N.REPL_COMMAND_LOAD_FAILED_INVALID, file)}\n`); } } catch (e) { - this.outputStream.write('Failed to load:' + file + '\n'); + this.outputStream.write( + `${I18N(I18N.REPL_COMMAND_LOAD_FAILED, file)}\n`); } this.displayPrompt(); } diff --git a/lib/string_decoder.js b/lib/string_decoder.js index 0c9fdfb416dd4e..361fb63b278ff3 100644 --- a/lib/string_decoder.js +++ b/lib/string_decoder.js @@ -1,13 +1,13 @@ 'use strict'; +const I18N = require('internal/messages'); const Buffer = require('buffer').Buffer; function assertEncoding(encoding) { // Do not cache `Buffer.isEncoding`, some modules monkey-patch it to support // additional encodings - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } + if (encoding && !Buffer.isEncoding(encoding)) + throw new I18N.Error(I18N.UNKNOWN_ENCODING, encoding); } // StringDecoder provides an interface for efficiently splitting a series of diff --git a/lib/sys.js b/lib/sys.js index a34ea0b899f824..f9df6e9dfd0982 100644 --- a/lib/sys.js +++ b/lib/sys.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const util = require('internal/util'); // the sys module was renamed to 'util'. @@ -7,4 +8,4 @@ const util = require('internal/util'); // sys is deprecated and shouldn't be used module.exports = require('util'); -util.printDeprecationMessage('sys is deprecated. Use util instead.'); +util.printDeprecationMessage(I18N(I18N.SYS_DEPRECATED)); diff --git a/lib/timers.js b/lib/timers.js index 66f77dfd0656df..f608374509846b 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -1,10 +1,10 @@ 'use strict'; +const I18N = require('internal/messages'); +const debug = I18N.debuglog('timer'); const Timer = process.binding('timer_wrap').Timer; const L = require('internal/linkedlist'); const assert = require('assert').ok; -const util = require('util'); -const debug = util.debuglog('timer'); const kOnTimeout = Timer.kOnTimeout | 0; // Timeout values > TIMEOUT_MAX are set to 1. @@ -57,17 +57,17 @@ function listOnTimeout() { var msecs = this.msecs; var list = this; - debug('timeout callback %d', msecs); + debug(I18N.TIMERS_DEBUG_CALLBACK, msecs); var now = Timer.now(); - debug('now: %s', now); + debug(I18N.TIMERS_DEBUG_NOW, now); var diff, first, threw; while (first = L.peek(list)) { diff = now - first._idleStart; if (diff < msecs) { list.start(msecs - diff, 0); - debug('%d list wait because diff is %d', msecs, diff); + debug(I18N.TIMERS_DEBUG_LIST_WAIT, msecs, diff); return; } else { L.remove(first); @@ -107,7 +107,7 @@ function listOnTimeout() { } } - debug('%d list empty', msecs); + debug(I18N.TIMERS_DEBUG_LIST_EMPTY, msecs); assert(L.isEmpty(list)); list.close(); delete lists[msecs]; @@ -125,7 +125,7 @@ function reuse(item) { var list = lists[item._idleTimeout]; // if empty - reuse the watcher if (list && L.isEmpty(list)) { - debug('reuse hit'); + debug(I18N.TIMERS_DEBUG_REUSE_HIT); list.stop(); delete lists[item._idleTimeout]; return list; @@ -138,7 +138,7 @@ function reuse(item) { const unenroll = exports.unenroll = function(item) { var list = reuse(item); if (list) { - debug('unenroll: list empty'); + debug(I18N.TIMERS_DEBUG_UNENROLL); list.close(); } // if active is called later, then we want to make sure not to insert again @@ -148,14 +148,11 @@ const unenroll = exports.unenroll = function(item) { // Does not start the time, just sets up the members needed. exports.enroll = function(item, msecs) { - if (typeof msecs !== 'number') { - throw new TypeError('"msecs" argument must be a number'); - } + if (typeof msecs !== 'number') + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'msecs', 'number'); - if (msecs < 0 || !isFinite(msecs)) { - throw new RangeError('"msecs" argument must be ' + - 'a non-negative finite number'); - } + if (msecs < 0 || !isFinite(msecs)) + throw new I18N.RangeError(I18N.TIMERS_NON_NEGATIVE_FINITE, 'msecs'); // if this item was already in a list somewhere // then we should unenroll it from that @@ -177,9 +174,8 @@ exports.enroll = function(item, msecs) { exports.setTimeout = function(callback, after) { - if (typeof callback !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } + if (typeof callback !== 'function') + throw new I18N.TypeError(I18N.FUNCTION_REQUIRED, 'callback'); after *= 1; // coalesce to number or NaN @@ -237,9 +233,8 @@ exports.clearTimeout = function(timer) { exports.setInterval = function(callback, repeat) { - if (typeof callback !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } + if (typeof callback !== 'function') + throw new I18N.TypeError(I18N.FUNCTION_REQUIRED, 'callback'); repeat *= 1; // coalesce to number or NaN @@ -427,9 +422,8 @@ Immediate.prototype._idlePrev = undefined; exports.setImmediate = function(callback, arg1, arg2, arg3) { - if (typeof callback !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } + if (typeof callback !== 'function') + throw new I18N.TypeError(I18N.FUNCTION_REQUIRED, 'callback'); var i, args; var len = arguments.length; @@ -523,7 +517,7 @@ function _makeTimerTimeout(timer) { domain.enter(); } - debug('unreftimer firing timeout'); + debug(I18N.TIMERS_DEBUG_UNREFTIMER_TIMEOUT); timer._called = true; _runOnTimeout(timer); @@ -544,7 +538,7 @@ function _runOnTimeout(timer) { function unrefTimeout() { var now = Timer.now(); - debug('unrefTimer fired'); + debug(I18N.TIMERS_DEBUG_UNREFTIMER_FIRED); var timeSinceLastActive; var nextTimeoutTime; @@ -602,9 +596,9 @@ function unrefTimeout() { if (minNextTimeoutTime !== TIMEOUT_MAX) { unrefTimer.start(minNextTimeoutTime - now, 0); unrefTimer.when = minNextTimeoutTime; - debug('unrefTimer rescheduled'); + debug(I18N.TIMERS_DEBUG_UNREFTIMER_RESCHED); } else if (L.isEmpty(unrefList)) { - debug('unrefList is empty'); + debug(I18N.TIMERS_DEBUG_UNREFLIST_EMPTY); } } @@ -617,11 +611,11 @@ exports._unrefActive = function(item) { L.remove(item); if (!unrefList) { - debug('unrefList initialized'); + debug(I18N.TIMERS_DEBUG_UNREFLIST_INIT); unrefList = {}; L.init(unrefList); - debug('unrefTimer initialized'); + debug(I18N.TIMERS_DEBUG_UNREFTIMER_INIT); unrefTimer = new Timer(); unrefTimer.unref(); unrefTimer.when = -1; @@ -638,9 +632,9 @@ exports._unrefActive = function(item) { if (unrefTimer.when === -1 || unrefTimer.when > when) { unrefTimer.start(msecs, 0); unrefTimer.when = when; - debug('unrefTimer scheduled'); + debug(I18N.TIMERS_DEBUG_UNREFTIMER_SCHED); } - debug('unrefList append to end'); + debug(I18N.TIMERS_DEBUG_UNREFLIST_APPEND); L.append(unrefList, item); }; diff --git a/lib/tls.js b/lib/tls.js index 24062832a5b9d3..ba32de4e7261b6 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const net = require('net'); const url = require('url'); const binding = process.binding('crypto'); @@ -110,7 +111,7 @@ exports.checkServerIdentity = function checkServerIdentity(host, cert) { ips = [], matchCN = true, valid = false, - reason = 'Unknown reason'; + reason = I18N(I18N.TLS_UNKNOWN_REASON); // There're several names to perform check against: // CN and altnames in certificate extension @@ -139,9 +140,8 @@ exports.checkServerIdentity = function checkServerIdentity(host, cert) { valid = ips.some(function(ip) { return ip === host; }); - if (!valid) { - reason = `IP: ${host} is not in the cert's list: ${ips.join(', ')}`; - } + if (!valid) + reason = I18N(I18N.TLS_HOST_NOT_IN_CERT_LIST, host, ips.join(', ')); } else if (cert.subject) { // Transform hostname to canonical form if (!/\.$/.test(host)) host += '.'; @@ -186,20 +186,18 @@ exports.checkServerIdentity = function checkServerIdentity(host, cert) { if (!valid) { if (cert.subjectaltname) { - reason = - `Host: ${host} is not in the cert's altnames: ` + - `${cert.subjectaltname}`; + reason = I18N(I18N.TLS_HOST_NOT_IN_CERT_ALTNAMES, + host, cert.subjectaltname); } else { - reason = `Host: ${host} is not cert's CN: ${cert.subject.CN}`; + reason = I18N(I18N.TLS_HOST_NOT_IN_CERT_CN, host, cert.subject.CN); } } } else { - reason = 'Cert is empty'; + reason = I18N(I18N.TLS_CERT_IS_EMPTY); } if (!valid) { - var err = new Error( - `Hostname/IP doesn't match certificate's altnames: "${reason}"`); + var err = new I18N.Error(I18N.TLS_HOSTNAME_NO_MATCH, reason); err.reason = reason; err.host = host; err.cert = cert; diff --git a/lib/url.js b/lib/url.js index 4de2fab3ff2dee..e2075abd78f2a5 100644 --- a/lib/url.js +++ b/lib/url.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const punycode = require('punycode'); exports.parse = urlParse; @@ -86,9 +87,8 @@ function urlParse(url, parseQueryString, slashesDenoteHost) { } Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { - if (typeof url !== 'string') { - throw new TypeError('Parameter "url" must be a string, not ' + typeof url); - } + if (typeof url !== 'string') + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'url', 'string'); // Copy chrome, IE, opera backslash-handling behavior. // Back slashes before the query string get converted to forward slashes @@ -354,8 +354,7 @@ function urlFormat(obj) { if (typeof obj === 'string') obj = urlParse(obj); else if (typeof obj !== 'object' || obj === null) - throw new TypeError('Parameter "urlObj" must be an object, not ' + - obj === null ? 'null' : typeof obj); + throw new I18N.TypeError(I18N.INVALID_ARG_TYPE, 'urlObj', 'object'); else if (!(obj instanceof Url)) return Url.prototype.format.call(obj); diff --git a/lib/util.js b/lib/util.js index 50cc5bc5b4b25d..6ebcc10b57d124 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1,5 +1,6 @@ 'use strict'; +const I18N = require('internal/messages'); const uv = process.binding('uv'); const Buffer = require('buffer').Buffer; const internalUtil = require('internal/util'); @@ -791,16 +792,13 @@ exports.log = function() { exports.inherits = function(ctor, superCtor) { if (ctor === undefined || ctor === null) - throw new TypeError('The constructor to "inherits" must not be ' + - 'null or undefined'); + throw new I18N.TypeError(I18N.UTIL_INHERITS_CONSTRUCTOR); if (superCtor === undefined || superCtor === null) - throw new TypeError('The super constructor to "inherits" must not ' + - 'be null or undefined'); + throw new I18N.TypeError(I18N.UTIL_INHERITS_SUPER_CONSTRUCTOR); if (superCtor.prototype === undefined) - throw new TypeError('The super constructor to "inherits" must ' + - 'have a prototype'); + throw new I18N.TypeError(I18N.UTIL_INHERITS_SUPER_CONSTRUCTOR_PROTOTYPE); ctor.super_ = superCtor; Object.setPrototypeOf(ctor.prototype, superCtor.prototype); @@ -829,26 +827,26 @@ exports.print = internalUtil.deprecate(function() { for (var i = 0, len = arguments.length; i < len; ++i) { process.stdout.write(String(arguments[i])); } -}, 'util.print is deprecated. Use console.log instead.'); +}, I18N(I18N.UTIL_PRINT_DEPRECATED)); exports.puts = internalUtil.deprecate(function() { for (var i = 0, len = arguments.length; i < len; ++i) { process.stdout.write(arguments[i] + '\n'); } -}, 'util.puts is deprecated. Use console.log instead.'); +}, I18N(I18N.UTIL_PUTS_DEPRECATED)); exports.debug = internalUtil.deprecate(function(x) { process.stderr.write('DEBUG: ' + x + '\n'); -}, 'util.debug is deprecated. Use console.error instead.'); +}, I18N(I18N.UTIL_DEBUG_DEPRECATED)); exports.error = internalUtil.deprecate(function(x) { for (var i = 0, len = arguments.length; i < len; ++i) { process.stderr.write(arguments[i] + '\n'); } -}, 'util.error is deprecated. Use console.error instead.'); +}, I18N(I18N.UTIL_ERROR_DEPRECATED)); exports._errnoException = function(err, syscall, original) { @@ -877,7 +875,7 @@ exports._exceptionWithHostPort = function(err, } if (additional) { - details += ' - Local (' + additional + ')'; + details += ` - ${I18N(I18N.UTIL_LOCAL)} (${additional})`; } var ex = exports._errnoException(err, syscall, details); ex.address = address; diff --git a/lib/zlib.js b/lib/zlib.js index 3e6f7b187632f2..1b7a434713a4bb 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -1,13 +1,13 @@ 'use strict'; +const I18N = require('internal/messages'); const Buffer = require('buffer').Buffer; const Transform = require('_stream_transform'); const binding = process.binding('zlib'); const util = require('util'); const assert = require('assert').ok; const kMaxLength = require('buffer').kMaxLength; -const kRangeErrorMessage = 'Cannot create final Buffer. ' + - 'It would be larger than 0x' + kMaxLength.toString(16) + ' bytes'; +const kRangeErrorMessage = I18N(I18N.ZLIB_RANGE_ERROR, kMaxLength.toString(16)); // zlib doesn't provide these, so kludge them in following the same // const naming scheme zlib uses. @@ -232,7 +232,7 @@ function zlibBufferSync(engine, buffer) { if (typeof buffer === 'string') buffer = new Buffer(buffer); if (!(buffer instanceof Buffer)) - throw new TypeError('Not a string or buffer'); + throw new I18N.TypeError(I18N.ZLIB_STRING_OR_BUFFER, 'buffer'); var flushFlag = binding.Z_FINISH; @@ -301,7 +301,7 @@ function Zlib(opts, mode) { opts.flush !== binding.Z_FULL_FLUSH && opts.flush !== binding.Z_FINISH && opts.flush !== binding.Z_BLOCK) { - throw new Error('Invalid flush flag: ' + opts.flush); + throw new I18N.Error(I18N.ZLIB_INVALID_FLUSH_FLAG, opts.flush); } } this._flushFlag = opts.flush || binding.Z_NO_FLUSH; @@ -309,28 +309,28 @@ function Zlib(opts, mode) { if (opts.chunkSize) { if (opts.chunkSize < exports.Z_MIN_CHUNK || opts.chunkSize > exports.Z_MAX_CHUNK) { - throw new Error('Invalid chunk size: ' + opts.chunkSize); + throw new I18N.Error(I18N.ZLIB_INVALID_CHUNK_SIZE, opts.chunkSize); } } if (opts.windowBits) { if (opts.windowBits < exports.Z_MIN_WINDOWBITS || opts.windowBits > exports.Z_MAX_WINDOWBITS) { - throw new Error('Invalid windowBits: ' + opts.windowBits); + throw new I18N.Error(I18N.ZLIB_INVALID_WINDOWBITS, opts.windowBits); } } if (opts.level) { if (opts.level < exports.Z_MIN_LEVEL || opts.level > exports.Z_MAX_LEVEL) { - throw new Error('Invalid compression level: ' + opts.level); + throw new I18N.Error(I18N.ZLIB_INVALID_COMPRESSION, opts.level); } } if (opts.memLevel) { if (opts.memLevel < exports.Z_MIN_MEMLEVEL || opts.memLevel > exports.Z_MAX_MEMLEVEL) { - throw new Error('Invalid memLevel: ' + opts.memLevel); + throw new I18N.Error(I18N.ZLIB_INVALID_MEMLEVEL, opts.memLevel); } } @@ -340,14 +340,13 @@ function Zlib(opts, mode) { opts.strategy != exports.Z_RLE && opts.strategy != exports.Z_FIXED && opts.strategy != exports.Z_DEFAULT_STRATEGY) { - throw new Error('Invalid strategy: ' + opts.strategy); + throw new I18N.Error(I18N.ZLIB_INVALID_STRATEGY, opts.strategy); } } if (opts.dictionary) { - if (!(opts.dictionary instanceof Buffer)) { - throw new Error('Invalid dictionary: it should be a Buffer instance'); - } + if (!(opts.dictionary instanceof Buffer)) + throw new I18N.Error(I18N.ZLIB_INVALID_DICTIONARY); } this._handle = new binding.Zlib(mode); @@ -392,20 +391,20 @@ util.inherits(Zlib, Transform); Zlib.prototype.params = function(level, strategy, callback) { if (level < exports.Z_MIN_LEVEL || level > exports.Z_MAX_LEVEL) { - throw new RangeError('Invalid compression level: ' + level); + throw new I18N.RangeError(I18N.ZLIB_INVALID_COMPRESSION, level); } if (strategy != exports.Z_FILTERED && strategy != exports.Z_HUFFMAN_ONLY && strategy != exports.Z_RLE && strategy != exports.Z_FIXED && strategy != exports.Z_DEFAULT_STRATEGY) { - throw new TypeError('Invalid strategy: ' + strategy); + throw new I18N.TypeError(I18N.ZLIB_INVALID_STRATEGY, strategy); } if (this._level !== level || this._strategy !== strategy) { var self = this; this.flush(binding.Z_SYNC_FLUSH, function() { - assert(!self._closed, 'zlib binding closed'); + assert(!self._closed, I18N(I18N.ZLIB_ASSERT_BINDING_CLOSED)); self._handle.params(level, strategy); if (!self._hadError) { self._level = level; @@ -419,7 +418,7 @@ Zlib.prototype.params = function(level, strategy, callback) { }; Zlib.prototype.reset = function() { - assert(!this._closed, 'zlib binding closed'); + assert(!this._closed, I18N(I18N.ZLIB_ASSERT_BINDING_CLOSED)); return this._handle.reset(); }; @@ -478,10 +477,10 @@ Zlib.prototype._transform = function(chunk, encoding, cb) { var last = ending && (!chunk || ws.length === chunk.length); if (chunk !== null && !(chunk instanceof Buffer)) - return cb(new Error('invalid input')); + return cb(new I18N.Error(I18N.ZLIB_INVALID_INPUT)); if (this._closed) - return cb(new Error('zlib binding closed')); + return cb(new I18N.Error(I18N.ZLIB_ASSERT_BINDING_CLOSED)); // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag. // If it's explicitly flushing at some other time, then we use @@ -519,7 +518,7 @@ Zlib.prototype._processChunk = function(chunk, flushFlag, cb) { error = er; }); - assert(!this._closed, 'zlib binding closed'); + assert(!this._closed, I18N(I18N.ZLIB_ASSERT_BINDING_CLOSED)); do { var res = this._handle.writeSync(flushFlag, chunk, // in @@ -545,7 +544,7 @@ Zlib.prototype._processChunk = function(chunk, flushFlag, cb) { return buf; } - assert(!this._closed, 'zlib binding closed'); + assert(!this._closed, I18N(I18N.ZLIB_ASSERT_BINDING_CLOSED)); var req = this._handle.write(flushFlag, chunk, // in inOff, // in_off @@ -562,7 +561,7 @@ Zlib.prototype._processChunk = function(chunk, flushFlag, cb) { return; var have = availOutBefore - availOutAfter; - assert(have >= 0, 'have should not go down'); + assert(have >= 0, I18N(I18N.ZLIB_ASSERT_HAVE_GO_DOWN)); if (have > 0) { var out = self._buffer.slice(self._offset, self._offset + have); diff --git a/node.gyp b/node.gyp index 672c3ce6691b9f..1278f31d743be3 100644 --- a/node.gyp +++ b/node.gyp @@ -74,6 +74,7 @@ 'lib/internal/freelist.js', 'lib/internal/linkedlist.js', 'lib/internal/module.js', + 'lib/internal/messages.js', 'lib/internal/readline.js', 'lib/internal/repl.js', 'lib/internal/socket_list.js', @@ -115,6 +116,7 @@ ], 'sources': [ + '/src/messages/messages.cc', 'src/debug-agent.cc', 'src/async-wrap.cc', 'src/env.cc', @@ -125,6 +127,7 @@ 'src/node.cc', 'src/node_buffer.cc', 'src/node_constants.cc', + 'src/node_messages.cc', 'src/node_contextify.cc', 'src/node_file.cc', 'src/node_http_parser.cc', @@ -150,6 +153,8 @@ 'src/udp_wrap.cc', 'src/uv.cc', # headers to make for a more pleasant IDE experience + 'src/messages/messages.h', + 'src/messages/en/messages.h', 'src/async-wrap.h', 'src/async-wrap-inl.h', 'src/base-object.h', @@ -160,6 +165,7 @@ 'src/handle_wrap.h', 'src/js_stream.h', 'src/node.h', + 'src/node_messages.h', 'src/node_buffer.h', 'src/node_constants.h', 'src/node_file.h', diff --git a/src/async-wrap.cc b/src/async-wrap.cc index c9f5caad1e4ea8..e05f4a3658b4b4 100644 --- a/src/async-wrap.cc +++ b/src/async-wrap.cc @@ -105,7 +105,7 @@ static void EnableHooksJS(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Local init_fn = env->async_hooks_init_function(); if (init_fn.IsEmpty() || !init_fn->IsFunction()) - return env->ThrowTypeError("init callback is not assigned to a function"); + return THROWI18NTYPEERROR(env, CALLBACK_NOT_ASSIGNED); env->async_hooks()->set_enable_callbacks(1); } @@ -120,10 +120,10 @@ static void SetupHooks(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (env->async_hooks()->callbacks_enabled()) - return env->ThrowError("hooks should not be set while also enabled"); + return THROWI18NERROR(env, HOOKSSHOULDNOTBESET); if (!args[0]->IsFunction()) - return env->ThrowTypeError("init callback must be a function"); + return THROWI18NTYPEERROR(env, INITCALLBACK); env->set_async_hooks_init_function(args[0].As()); diff --git a/src/env-inl.h b/src/env-inl.h index f73e9c6ba2000a..a2acfae7054f18 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -460,6 +460,54 @@ inline void Environment::ThrowUVException(int errorno, UVException(isolate(), errorno, syscall, message, path, dest)); } +inline void Environment::ThrowI18NError(const char* msg, + const char* key) { + isolate()->ThrowException(I18NError(isolate(), key, msg)); +} + +inline void Environment::ThrowI18NTypeError(const char* msg, + const char* key) { + isolate()->ThrowException(I18NTypeError(isolate(), key, msg)); +} + +inline void Environment::ThrowI18NRangeError(const char* msg, + const char* key) { + isolate()->ThrowException(I18NRangeError(isolate(), key, msg)); +} + +inline void Environment::ThrowI18NErrorV(const char* msg, + const char* key, + ...) { + va_list args; + va_start(args, key); + char tmp[1024]; + vsnprintf(tmp, sizeof(tmp), msg, args); + isolate()->ThrowException(I18NError(isolate(), key, tmp)); + va_end(args); +} + +inline void Environment::ThrowI18NTypeErrorV(const char* msg, + const char* key, + ...) { + va_list args; + va_start(args, key); + char tmp[1024]; + vsnprintf(tmp, sizeof(tmp), msg, args); + isolate()->ThrowException(I18NTypeError(isolate(), key, tmp)); + va_end(args); +} + +inline void Environment::ThrowI18NRangeErrorV(const char* msg, + const char* key, + ...) { + va_list args; + va_start(args, key); + char tmp[1024]; + vsnprintf(tmp, sizeof(tmp), msg, args); + isolate()->ThrowException(I18NRangeError(isolate(), key, tmp)); + va_end(args); +} + inline v8::Local Environment::NewFunctionTemplate(v8::FunctionCallback callback, v8::Local signature) { diff --git a/src/env.cc b/src/env.cc index fa8cc0d1addfd7..8ef00a229c268d 100644 --- a/src/env.cc +++ b/src/env.cc @@ -27,7 +27,7 @@ void Environment::PrintSyncTrace() const { Local stack = StackTrace::CurrentStackTrace(isolate(), 10, StackTrace::kDetailed); - fprintf(stderr, "(node:%d) WARNING: Detected use of sync API\n", getpid()); + fprintf(stderr, STR_SYNC_WARNING, getpid()); for (int i = 0; i < stack->GetFrameCount() - 1; i++) { Local stack_frame = stack->GetFrame(i); @@ -38,10 +38,10 @@ void Environment::PrintSyncTrace() const { if (stack_frame->IsEval()) { if (stack_frame->GetScriptId() == Message::kNoScriptIdInfo) { - fprintf(stderr, " at [eval]:%i:%i\n", line_number, column); + fprintf(stderr, " " STR_AT " [eval]:%i:%i\n", line_number, column); } else { fprintf(stderr, - " at [eval] (%s:%i:%i)\n", + " " STR_AT " [eval] (%s:%i:%i)\n", *script_name, line_number, column); @@ -50,10 +50,11 @@ void Environment::PrintSyncTrace() const { } if (fn_name_s.length() == 0) { - fprintf(stderr, " at %s:%i:%i\n", *script_name, line_number, column); + fprintf(stderr, " " STR_AT " %s:%i:%i\n", + *script_name, line_number, column); } else { fprintf(stderr, - " at %s (%s:%i:%i)\n", + " " STR_AT " %s (%s:%i:%i)\n", *fn_name_s, *script_name, line_number, diff --git a/src/env.h b/src/env.h index 743bf057e8584d..75e1763dd693c4 100644 --- a/src/env.h +++ b/src/env.h @@ -478,6 +478,28 @@ class Environment { const char* path = nullptr, const char* dest = nullptr); + inline void ThrowI18NErrorV(const char* msg, const char* key, ...); + inline void ThrowI18NTypeErrorV(const char* msg, const char* key, ...); + inline void ThrowI18NRangeErrorV(const char* msg, const char* key, ...); + + inline void ThrowI18NError(const char* msg, const char* key); + inline void ThrowI18NTypeError(const char* msg, const char* key); + inline void ThrowI18NRangeError(const char* msg, const char* key); + + #define THROWI18NERROR(env, key) \ + env->ThrowI18NError(STR_ ## key, #key) + #define THROWI18NTYPEERROR(env, key) \ + env->ThrowI18NTypeError(STR_ ## key, #key) + #define THROWI18NRANGEERROR(env, key) \ + env->ThrowI18NRangeError(STR_ ## key, #key) + + #define VTHROWI18NERROR(env, key, ...) \ + env->ThrowI18NErrorV(STR_ ## key, #key, __VA_ARGS__) + #define VTHROWI18NTYPEERROR(env, key, ...) \ + env->ThrowI18NTypeErrorV(STR_ ## key, #key, __VA_ARGS__) + #define VTHROWI18NRANGEERROR(env, key, ...) \ + env->ThrowI18NRangeErrorV(STR_ ## key, #key, __VA_ARGS__) + // Convenience methods for contextify inline static void ThrowError(v8::Isolate* isolate, const char* errmsg); inline static void ThrowTypeError(v8::Isolate* isolate, const char* errmsg); diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc index 7768f94459c16a..62712352aa51a6 100644 --- a/src/fs_event_wrap.cc +++ b/src/fs_event_wrap.cc @@ -87,7 +87,7 @@ void FSEventWrap::Start(const FunctionCallbackInfo& args) { FSEventWrap* wrap = Unwrap(args.Holder()); if (args.Length() < 1 || !args[0]->IsString()) { - return env->ThrowTypeError("filename must be a valid string"); + return THROWI18NTYPEERROR(env, INVALID_FILENAME); } node::Utf8Value path(env->isolate(), args[0]); diff --git a/src/messages/en/messages.h b/src/messages/en/messages.h new file mode 100644 index 00000000000000..5b9d88969710cb --- /dev/null +++ b/src/messages/en/messages.h @@ -0,0 +1,790 @@ +#ifndef SRC_NODE_MESSAGES_SRC_H_ +#define SRC_NODE_MESSAGES_SRC_H_ + +// node --help output + +#if HAVE_OPENSSL +#define NODE_HELP_OPENSSL \ + " --tls-cipher-list=val use an alternative default TLS cipher list\n" +#else // !HAVE_OPENSSL +#define NODE_HELP_OPENSSL "" +#endif // HAVE_OPENSSL + +#if defined(NODE_HAVE_I18N_SUPPORT) +#if !defined(NODE_HAVE_SMALL_ICU) +#define NODE_HELP_I18N_SMALL_ICU \ + " note: linked-in ICU data is\n" \ + " present.\n" +#else // defined(NODE_HAVE_SMALL_ICU) +#define NODE_HELP_I18N_SMALL_ICU "" +#endif // !defined(NODE_HAVE_SMALL_ICU) +#define NODE_HELP_I18N \ + " --icu-data-dir=dir set ICU data load path to dir\n" \ + " (overrides NODE_ICU_DATA)\n" \ + NODE_HELP_I18N_SMALL_ICU + +#define NODE_HELP_ICU_DATA \ + "NODE_ICU_DATA data path for ICU (Intl object) data\n" \ + " (will extend linked-in data)\n" + +#else // !defined(NODE_HAVE_I18N_SUPPORT) +#define NODE_HELP_ICU_DATA "" +#define NODE_HELP_I18N "" +#endif // defined(NODE_HAVE_I18N_SUPPORT) + +// Determine the path separator +#ifdef _WIN32 +#define NODE_HELP_SEP ";" +#else +#define NODE_HELP_SEP ":" +#endif + +#define STR_NODEHELP \ +"Usage: node [options] [ -e script | script.js ] [arguments] \n" \ + " node debug script.js [arguments] \n" \ + "\n" \ + "Options:\n" \ + " -v, --version print Node.js version\n" \ + " -e, --eval script evaluate script\n" \ + " -p, --print evaluate script and print result\n" \ + " -c, --check syntax check script without executing\n" \ + " -i, --interactive always enter the REPL even if stdin\n" \ + " does not appear to be a terminal\n" \ + " -r, --require module to preload (option can be repeated)\n" \ + " --no-deprecation silence deprecation warnings\n" \ + " --throw-deprecation throw an exception anytime a deprecated " \ + "function is used\n" \ + " --trace-deprecation show stack traces on deprecations\n" \ + " --trace-sync-io show stack trace when use of sync IO\n" \ + " is detected after the first tick\n" \ + " --track-heap-objects track heap object allocations for heap " \ + "snapshots\n" \ + " --prof-process process v8 profiler output generated\n" \ + " using --prof\n" \ + " --v8-options print v8 command line options\n" \ + NODE_HELP_OPENSSL \ + NODE_HELP_I18N \ + "\n" \ + "Environment variables:\n" \ + "NODE_PATH '" NODE_HELP_SEP "'-separated list of " \ + "directories\n" \ + " prefixed to the module search path.\n" \ + "NODE_DISABLE_COLORS set to 1 to disable colors in the REPL\n" \ + NODE_HELP_ICU_DATA \ + "NODE_REPL_HISTORY path to the persistent REPL history file\n" \ + "\n" \ + "Documentation can be found at https://nodejs.org/\n" + +// Other messages ... + +#define NODE_MESSAGE_UNKNOWN "(Message Unknown)" + +#define NODE_DEPRECATE_MESSAGE(what, alternate) \ + what " is deprecated. Use " alternate " instead." + +#define STR_SYNC_WARNING "(node:%d) WARNING: Detected use of sync API\n" +#define STR_AT "at" +#define STR_OPENSSL_FIPS_FAIL "openssl fips failed: %s\n" +#define STR_PROCESS_TICKDOMAIN_NONFUNCTION \ + "process._tickDomainCallback assigned to non-function\n" +#define STR_RAW_ENCODING_REMOVED \ + "'raw' encoding (array of integers) has been removed. Use 'binary'.\n" +#define STR_MODULE_VERSION_MISMATCH \ + "Module version mismatch. Expected %d, got %d." +#define STR_BINDING "Binding %s" +#define STR_NO_SUCH_MODULE "No such module: %s" +#define STR_NO_SUCH_MODULE_LINKED "No such module was linked: %s" +#define STR_DEBUGPORT_OUTOFRANGE "Debug port must be in range 1024 to 65535.\n" +#define STR_REQUIRES_ARGUMENT "%s: %s requires an argument\n" +#define STR_START_DEBUGGER_FAIL "Starting debugger on port %d failed\n" +#define STR_START_DEBUGGER_AGENT "Starting debugger agent.\n" +#define STR_BAD_OPTION "bad option" + +// The messages used in src/*.cc +// These are used only within the Node.js native source +#define STR_CONVERT_ARGS_TO_UTF8_FAIL "Could not convert arguments to utf8." +#define STR_OUTOFMEMORY "Out of memory" +#define STR_CALLBACK_NOT_ASSIGNED "init callback is not assigned to a function" +#define STR_HOOKSSHOULDNOTBESET "hooks should not be set while also enabled" +#define STR_INITCALLBACK "init callback must be a function" +#define STR_INVALID_FILENAME "filename must be a valid string" +#define STR_INDEX_OUT_OF_RANGE "out of range index" +#define STR_ARGUMENT_BUFFER "argument should be a Buffer" +#define STR_ARGUMENT_STRING "Argument must be a string" +#define STR_ARGUMENT_ARRAYBUFFER "argument is not an ArrayBuffer" +#define STR_UNABLE_TO_SET_PROTOTYPE "Unable to set Object prototype" +#define STR_INVALID_HEX "Invalid hex string" +#define STR_OFFSET_OUTOFBOUNDS "Offset is out of bounds" +#define STR_LENGTH_OUTOFBOUNDS "length out of bounds" +#define STR_SANDBOX_OBJECT "sandbox argument must be an object." +#define STR_VMSCRIPT_AS_CONSTRUCTOR "Must call vm.Script as a constructor." +#define STR_CONTEXTIFIED_MUST_BE_OBJECT \ + "contextifiedSandbox argument must be an object." +#define STR_SANDBOX_ARGUMENT_CONVERSION \ + "sandbox argument must have been converted to a context." +#define STR_OPTIONS_OBJECT "options must be an object" +#define STR_TIMEOUT_POSITIVE "timeout must be a positive number" +#define STR_CANNOT_CALL_SCRIPT_METHODS \ + "Script methods can only be called on script instances." +#define STR_SCRIPT_EXECUTION_TIMEDOUT "Script execution timed out." +#define STR_NOT_STRING_BUFFER "Not a string or buffer" +#define STR_NOT_BUFFER "Not a buffer" +#define STR_SSLV2_METHODS_DISABLED "SSLv2 methods disabled" +#define STR_SSLV3_METHODS_DISABLED "SSLv3 methods disabled" +#define STR_UNKNOWN_METHOD "Unknown method" +#define STR_BAD_PARAMETER "Bad parameter" +#define STR_PEM_READ_BIO "PEM_read_bio_PrivateKey" +#define STR_CTX_USE_PRIVATEKEY "SSL_CTX_use_PrivateKey" +#define STR_CTX_USE_CERT_CHAIN "SSL_CTX_use_certificate_chain" +#define STR_FIRST_ARGUMENT_STRING "First argument should be a string" +#define STR_INVALID_CURVE_NAME "First argument should be a valid curve name" +#define STR_SMALL_DH_PARAMETER "DH parameter is less than 1024 bits" +#define STR_WARN_SMALL_DH "WARNING: DH parameter is less than 2048 bits" +#define STR_SET_DH_ERROR "Error setting temp DH parameter" +#define STR_CTX_SET_SESSION_ID_ERR "SSL_CTX_set_session_id_context error" +#define STR_UNABLE_TO_LOAD_BIO "Unable to load BIO" +#define STR_FAILED_FETCH_TLS_TICKET "Failed to fetch tls ticket keys" +#define STR_BAD_ARGUMENT "Bad argument" +#define STR_FIRST_ARGUMENT_BUFFER "Must give a Buffer as first argument" +#define STR_SSL_SET_SESSION_ERROR "SSL_set_session error" +#define STR_CERTCBDONE "CertCbDone" +#define STR_FIRST_ARGUMENT_SECURECONTEXT \ + "First argument must be a tls module SecureContext" +#define STR_TAKES_THREE_ARGS "Takes 3 parameters" +#define STR_SECOND_ARGUMENT_BUFFER "Second argument should be a buffer" +#define STR_OFF_LEN_BUFLEN "off + len > buffer.length" +#define STR_FIRST_ARGUMENT_FUNCTION "Must give a Function as first argument" +#define STR_CRYPTO_CREATECIPHER_NOT_SUPPORTED \ + "crypto.createCipher() is not supported in FIPS mode." +#define STR_UNKNOWN_CIPHER "Unknown cipher" +#define STR_INVALID_KEYLEN "Invalid key length" +#define STR_MUST_GIVE_CIPHER_TYPE "Must give cipher-type, key" +#define STR_INVALID_IVLEN "Invalid IV length" +#define STR_MUST_GIVE_CIPHER_TYPE_KEY_IV \ + "Must give cipher-type, key, and iv as argument" +#define STR_CANNOT_GET_AUTH_TAG \ + "Attempting to get auth tag in unsupported state" +#define STR_CANNOT_SET_AUTH_TAG \ + "Attempting to set auth tag in unsupported state" +#define STR_CANNOT_SET_AAD "Attempting to set AAD in unsupported state" +#define STR_CANNOT_ADD_DATA "Trying to add data in unsupported state" +#define STR_UNSUPPORTED_STATE_UNABLE_TO_AUTH \ + "Unsupported state or unable to authenticate data" +#define STR_UNSUPOPORTED_STATE "Unsupported state" +#define STR_UNKNOWN_MESSAGE_DIGEST "Unknown message digest" +#define STR_MUST_GIVE_HASHTYPE "Must give hashtype string, key as arguments" +#define STR_HMACUPDATE_FAIL "HmacUpdate fail" +#define STR_MUST_GIVE_HASHTYPE_ARG "Must give hashtype string as argument" +#define STR_DIGEST_METHOD_NOT_SUPPORTED "Digest method not supported" +#define STR_HASHUPDATE_FAIL "HashUpdate fail" +#define STR_NOT_INITIALIZED "Not initialized" +#define STR_EVP_SIGNINIT_EX_FAIL "EVP_SignInit_ex failed" +#define STR_EVP_SIGNUPDATE_FAIL "EVP_SignUpdate failed" +#define STR_PEM_READ_BIO_PRIVATEKEY_FAIL "PEM_read_bio_PrivateKey failed" +#define STR_PEM_READ_BIO_PUBKEY_FAIL "PEM_read_bio_PUBKEY failed" +#define STR_MUST_GIVE_SIGNTYPE_ARG "Must give signtype string as argument" +#define STR_MUST_GIVE_VERIFYTYPE_ARG "Must give verifytype string as argument" +#define STR_NO_GROUP_NAME "No group name given" +#define STR_INIT_FAILED "Initialization failed" +#define STR_UNKNOWN_GROUP "Unknown group" +#define STR_KEY_GENERATION_FAIL "Key generation failed" +#define STR_NO_PUBKEY "No public key - did you forget to generate one?" +#define STR_NO_PVTKEY "No private key - did you forget to generate one?" +#define STR_FIRST_ARGUMENT_PUBKEY \ + "First argument must be other party's public key" +#define STR_INVALID_KEY "Invalid Key" +#define STR_SUPPLIED_KEY_SMALL "Supplied key is too small" +#define STR_SUPPLIED_KEY_LARGE "Supplied key is too large" +#define STR_FIRST_ARGUMENT_PUBKEY2 "First argument must be public key" +#define STR_FIRST_ARGUMENT_PVTKEY "First argument must be private key" +#define STR_CREATE_ECKEY_FAIL "Failed to create EC_KEY using curve name" +#define STR_GENERATE_ECKEY_FAIL "Failed to generate EC_KEY" +#define STR_ALLOCATE_ECPOINT_FAIL \ + "Failed to allocate EC_POINT for a public key" +#define STR_TRANSLATE_BUFFER_FAIL "Failed to translate Buffer to a EC_POINT" +#define STR_INVALID_KEYPAIR "Invalid key pair" +#define STR_COMPUTEECDH_FAIL "Failed to compute ECDH key" +#define STR_GETECDH_FAIL "Failed to get ECDH public key" +#define STR_GET_PUBKEY_FAIL "Failed to get public key length" +#define STR_GET_PUBKEY_FAIL2 "Failed to get public key" +#define STR_GET_ECDH_PVTKEY_FAIL "Failed to get ECDH private key" +#define STR_CONVERT_ECDH_PVTKEY_FAIL \ + "Failed to convert ECDH private key to Buffer" +#define STR_CONVERT_BUFFER_BN_FAIL "Failed to convert Buffer to BN" +#define STR_PVTKEY_NOTVALID_CURVE \ + "Private key is not valid for specified curve." +#define STR_CONVERT_BN_PVTKEY_FAIL "Failed to convert BN to a private key" +#define STR_GENERATE_ECDH_PUBKEY_FAIL "Failed to generate ECDH public key" +#define STR_SET_PUBKEY_FAIL "Failed to set generated public key" +#define STR_CONVERT_BUFFER_ECPOINT_FAIL "Failed to convert Buffer to EC_POINT" +#define STR_ITERATIONS_NOT_NUMBER "Iterations not a number" +#define STR_BAD_ITERATIONS "Bad iterations" +#define STR_KEYLEN_NOT_NUMBER "Key length not a number" +#define STR_BAD_KEYLEN "Bad key length" +#define STR_BAD_DIGEST_NAME "Bad digest name" +#define STR_OPERATION_NOT_SUPPORTED "Operation not supported" +#define STR_POSITIVE_NUMBER "size must be a number >= 0" +#define STR_SIZE_NOT_VALID_SMI "size is not a valid Smi" +#define STR_SSL_CTL_NEW_FAIL "SSL_CTX_new() failed." +#define STR_SSL_NEW_FAIL "SSL_new() failed." +#define STR_MISSING_ARGUMENT "Missing argument" +#define STR_ENGINE_NOT_FOUND "Engine \"%s\" was not found" +#define STR_EXPECTED_OBJECT_TO_CONTAIN_TYPED_MEMBER \ + "expected object for %s to contain %s member %s" +#define STR_EXPECTED_CONNECTION_OBJECT \ + "expected argument %s to be a connection object" +#define STR_EXPECTED_OBJECT_FOR_REQUEST_TO_CONTAIN_STRING_HEADERS \ + "expected object for request to contain string member headers" +#define STR_UNKNOWN_SYMLINK_TYPE "Unknown symlink type" +#define STR_NOT_AN_INTEGER "Not an integer" +#define STR_FIRST_ARGUMENT_FILEDESCRIPTOR \ + "First argument must be file descriptor" +#define STR_OFF_LEN_OVERFLOW "off + len overflow" +#define STR_ARRAY_ELEMENT_BUFFERS "Array elements all need to be buffers" +#define STR_LENGTH_BEYOND_BUFFER "Length extends beyond buffer" +#define STR_FD_BUFFER_REQUIRED "fd and buffer are required" +#define STR_FD_FILE_DESCRIPTOR "fd must be a file descriptor" +#define STR_PATH_MODE_REQUIRED "path and mode are required" +#define STR_PATH_STRING "path must be a string" +#define STR_MODE_INTEGER "mode must be an integer" +#define STR_FD_REQUIRED "fd is required" +#define STR_PATH_REQUIRED "path is required" +#define STR_TARGET_PATH_REQUIRED "target path required" +#define STR_DEST_PATH_REQUIRED "dest path required" +#define STR_SRC_PATH_REQUIRED "src path required" +#define STR_TARGET_PATH_STRING "target path must be a string" +#define STR_SRC_PATH_STRING "src path must be a string" +#define STR_DEST_PATH_STRING "dest path must be a string" +#define STR_OLD_PATH_REQUIRED "old path required" +#define STR_NEW_PATH_REQUIRED "new path required" +#define STR_OLD_PATH_STRING "old path must be a string" +#define STR_NEW_PATH_STRING "new path must be a string" +#define STR_FD_LENGTH_REQUIRED "fd and length are required" +#define STR_FLAGS_REQUIRED "flags required" +#define STR_MODE_REQUIRED "mode required" +#define STR_FLAGS_INT "flags must be an int" +#define STR_FD_MODE_REQUIRED "fd and mode are required" +#define STR_UID_REQUIRED "uid required" +#define STR_GID_REQUIRED "gid required" +#define STR_UID_UINT "uid must be an unsigned int" +#define STR_GID_UINT "gid must be an unsigned int" +#define STR_FD_INTEGER "fd must be an int" +#define STR_ATIME_REQUIRED "atime required" +#define STR_MTIME_REQUIRED "mtime required" +#define STR_ATIME_NUMBER "atime must be a number" +#define STR_MTIME_NUMBER "mtime must be a number" +#define STR_OBJ_OBJECT "obj must be an object" +#define STR_NAME_STRING "name must be a string" +#define STR_V8_FLAG_REQUIRED "v8 flag is required" +#define STR_V8_FLAG_STRING "v8 flag must be a string" +#define STR_UNEXPECTED_EOF "unexpected end of file" +#define STR_MISSING_DICTIONARY "Missing dictionary" +#define STR_BAD_DICTIONARY "Bad dictionary" +#define STR_ZLIB_ERROR "Zlib error" +#define STR_INIT_ERROR "Init error" +#define STR_FAILED_TO_SET_DICTIONARY "Failed to set dictionary" +#define STR_FAILED_TO_SET_PARAMETERS "Failed to set parameters" +#define STR_FAILED_TO_RESET_STREAM "Failed to reset stream" +#define STR_UID_OUTOFRANGE "options.uid is out of range" +#define STR_GID_OUTOFRANGE "options.gid is out of range" +#define STR_OPTIONS_UID_NUMBER "options.uid should be a number" +#define STR_OPTIONS_GID_NUMBER "options.gid should be a number" +#define STR_BAD_INPUT_STRING "Bad input string" +#define STR_FIRST_ARGUMENT_STREAMWRAP \ + "First argument should be a StreamWrap instance" +#define STR_SECOND_ARGUMENT_SECURECONTEXT \ + "Second argument should be a SecureContext instance" +#define STR_THIRD_AGUMENT_BOOLEAN "Third argument should be boolean" +#define STR_ALREADY_STARTED "Already started." +#define STR_BAD_ARGUMENTS_TWO_BOOLEANS \ + "Bad arguments, expected two booleans" +#define STR_SETVERIFYMODE_AFTER_DESTROYSSL "SetVerifyMode after destroySSL" +#define STR_ENABLESESSIONCALLBACKS_AFTER_DESTROYSSL \ + "EnableSessionCallbacks after destroySSL" +#define STR_ERR_NOT_ZERO "err >= 0" + +// The messages used in lib/*.js +// These are exposes as constants on require('internal/messages') +#define NODE_MESSAGES(XX) \ + XX(ASSERTION_ERROR, "assertion error") \ + XX(HRTIME_ARRAY, "process.hrtime() only accepts an Array tuple") \ + XX(FUNCTION_REQUIRED, "'{0}' must be a function") \ + XX(UNKNOWN_STREAM_FILE_TYPE, "Unknown stream file type!") \ + XX(UNKNOWN_STDIN_FILE_TYPE, "Unknown stdin file type!") \ + XX(CLOSE_STDOUT, "process.stdout cannot be closed.") \ + XX(CLOSE_STDERR, "process.stderr cannot be closed.") \ + XX(INVALID_PID, "invalid pid") \ + XX(UNKNOWN_SIGNAL, "Unknown signal: {0}") \ + XX(UNKNOWN_NATIVE_MODULE, "No such native module") \ + XX(UNEXPECTED, "unexpected {0}") \ + XX(INDEX_OUT_OF_RANGE, "index of out range") \ + XX(OUT_OF_BOUNDS_WRITE, "Attempt to write outside bounds") \ + XX(DEBUGAGENT_LISTENING, "Debugger listening on port {0}") \ + XX(DEBUGAGENT_NO_BINDINGS, "Debugger agent running without bindings!") \ + XX(DEBUGAGENT_EXPECTED_HEADER, \ + "Expected header, but failed to parse it") \ + XX(DEBUGAGENT_EXPECTED_CONTENT_LENGTH, "Expected content-length") \ + XX(DEBUGGER_USAGE, "Usage") \ + XX(DEBUGGER_ERROR, \ + "There was an internal error in the Node.js debugger. " \ + "Please report this error.") \ + XX(DEBUGGER_UNKNOWN_STATE, "Unknown state") \ + XX(DEBUGGER_PROBLEM_REQLOOKUP, "problem with reqLookup") \ + XX(DEBUGGER_NO_FRAMES, "No frames") \ + XX(DEBUGGER_COMMANDS, "Commands") \ + XX(DEBUGGER_BREAK_IN, "break in") \ + XX(DEBUGGER_EXCEPTION_IN, "exception in") \ + XX(DEBUGGER_APP_NOT_RUNNING, \ + "The application is not running. Try `run` instead") \ + XX(DEBUGGER_APP_RUNNING, \ + "The application is already running. Try `restart` instead") \ + XX(DEBUGGER_CANNOT_LIST_SOURCE, \ + "Source code cannot be listed right now'") \ + XX(DEBUGGER_CANNOT_REQUEST_BACKTRACE, \ + "Backtrace cannot be requested right now") \ + XX(DEBUGGER_EMPTY_STACK, "(empty stack)") \ + XX(DEBUGGER_WATCHERS, "Watchers") \ + XX(DEBUGGER_CANNOT_DETERMINE_SCRIPT, \ + "Cannot determine the current script, " \ + "make sure the debugged process is paused.") \ + XX(DEBUGGER_SCRIPT_NAME_AMBIGUOUS, "Script name is ambiguous") \ + XX(DEBUGGER_LINE_POSITIVE, "Line must be a positive value") \ + XX(DEBUGGER_SCRIPT_NOT_LOADED, \ + "Warning: script '{0}' was not loaded yet.'") \ + XX(DEBUGGER_SCRIPT_NOT_FOUND, "Script '{0}' not found") \ + XX(DEBUGGER_BREAKPOINT_NOT_FOUND, "Breakpoint not found on line {0}") \ + XX(DEBUGGER_REPL_EXIT, "Press Ctrl + C to leave debug repl") \ + XX(DEBUGGER_TARGET_PROCESS, "Target process {0} does not exist.") \ + XX(DEBUGGER_READY, "ok") \ + XX(DEBUGGER_RESTORING_BREAKPOINT, "Restoring breakpoint") \ + XX(DEBUGGER_PROGRAM_TERMINATED, "program terminated") \ + XX(DEBUGGER_UNHANDLED_RESPONSE, "unhandled res") \ + XX(DEBUGGER_CONNECTION_FAILED, "failed to connect, please retry") \ + XX(DEBUGGER_CONNECTING, "connecting to") \ + XX(HTTP_CLIENT_DOMAIN_NAME, "Unable to determine the domain name") \ + XX(HTTP_CLIENT_UNESCAPED_PATH, \ + "Request path contains unescaped characters") \ + XX(HTTP_CLIENT_UNEXPECTED_PROTOCOL, \ + "Protocol '{0}' not supported. Expected '{1}'") \ + XX(HTTP_INVALID_TOKEN, "'{0}' must be a valid HTTP token") \ + XX(NET_SOCKET_HANGUP, "socket hang up") \ + XX(INVALID_ARG_TYPE, "'{0}' argument must be a(n) {1}") \ + XX(INVALID_OPTION_TYPE, "'{0}' option must be a(n) {1}") \ + XX(REQUIRED_ARG, "'{0}' argument is required") \ + XX(HTTP_OUTGOING_SET_AFTER_SEND, \ + "Cannot set headers after they have already been sent") \ + XX(HTTP_OUTGOING_REMOVE_AFTER_SEND, \ + "Cannot remove headers after they have already been sent") \ + XX(HTTP_OUTGOING_RENDER_AFTER_SEND, \ + "Cannot render headers after they have already been sent") \ + XX(WRITE_AFTER_END, "write after end") \ + XX(FIRST_ARGUMENT_STRING_OR_BUFFER, \ + "The first argument must be a string or Buffer") \ + XX(HTTP_OUTGOING_MESSAGE_END, "outgoing message end.") \ + XX(STREAM_READABLE_PUSH_AFTER_END, "stream.push() after EOF") \ + XX(STREAM_READABLE_UNSHIFT_AFTER_END, "stream.unshift() after end event") \ + XX(STREAM_READABLE_INVALID_CHUNK, "Invalid non-string/buffer chunk") \ + XX(NOT_IMPLEMENTED, "not implemented") \ + XX(STREAM_READABLE_STREAM_NOT_EMPTY, \ + "'endReadable()' called on non-empty stream") \ + XX(STREAM_READABLE_CALL_PAUSE_FLOWING, "call pause flowing = {0}") \ + XX(STREAM_READABLE_READEMITREADABLE, "read: emitReadable {0} {1}") \ + XX(STREAM_TRANSFORM_NO_WRITECB, "no writecb in Transform class") \ + XX(STREAM_TRANSFORM_DONE_NOT_EMPTY, \ + "Calling transform done when ws.length != 0") \ + XX(STREAM_TRANSFORM_DONE_STILL_GOING, \ + "Calling transform done when still transforming") \ + XX(STREAM_WRAP_HAS_STRINGDECODER, "Stream has StringDecoder") \ + XX(STREAM_WRITABLE_CANNOT_PIPE_NOT_READABLE, "Cannot pipe, not readable") \ + XX(UNKNOWN_ENCODING, "Unknown encoding: {0}") \ + XX(NO_OPENSSL, "Node.js was not compiled with OpenSSL crypto support") \ + XX(TLS_RENEGOTIATION_ATTACK, "TLS session renegotiation attack detected") \ + XX(TLS_CALLBACK_CALLED_TWICE, "callback was called more than once") \ + XX(SOCKET_CLOSED, "Socket is closed") \ + XX(TLS_FAILED_TO_RENEGOTIATE, "Failed to renegotiate") \ + XX(TLS_HANDSHAKE_TIMEOUT, "TLS handshake timeout") \ + XX(TLS_DH_PARAMETER_SIZE_SMALL, "DH parameter size {0} is less than {1}") \ + XX(ASSERT_MISSING_EXCEPTION, "Missing expected exception{0}") \ + XX(ASSERT_UNWANTED_EXCEPTION, "Got unwanted exception{0}") \ + XX(BUFFER_ENCODING_STR, \ + "If encoding is specified then the first argument must be a string") \ + XX(BUFFER_INVALID_ARG, "'{0}' must be a number, Buffer, array or string") \ + XX(BUFFER_INVALID_ARG2, "'{0}' must be a string, number, or Buffer") \ + XX(BUFFER_INVALID_ARGS, "Arguments must be Buffers") \ + XX(BUFFER_TOSTRING_FAILED, "'toString()' failed") \ + XX(BUFFER_OUTOFBOUNDS_ARG, "'{0}' argument is out of bounds") \ + XX(CHILD_PROCESS_ARG_OPTION, "Incorrect value of args option") \ + XX(CHILD_PROCESS_COMMAND_FAILED, "Command failed: {0}\n{1}") \ + XX(CHILD_PROCESS_MAXBUFFER_EXCEEDED, "{0} maxBuffer exceeded") \ + XX(CHILD_PROCESS_INVALID_STDIO, \ + "stdio{0} should be Buffer or string not {1}") \ + XX(CHILD_PROCESS_SPAWNSYNC, "spawnSync {0}") \ + XX(CHILD_PROCESS_CHANNEL_CLOSED, "channel closed") \ + XX(CHILD_PROCESS_BAD_HANDLE_TYPE, "This handle type cannot be sent") \ + XX(CHILD_PROCESS_IPC_DISCONNECTED, "IPC channel is already disconnected") \ + XX(CHILD_PROCESS_INCORRECT_STDIO, "Incorrect value of stdio option: {0}") \ + XX(CHILD_PROCESS_ONE_IPC, "Child process can have only one IPC pipe") \ + XX(CHILD_PROCESS_NOIPC_SYNC, "IPC cannot be used with synchronous fork") \ + XX(CHILD_PROCESS_BUFFER_NOT_SUPPORTED, \ + "Asynchronous forks do not support Buffer input: {0}") \ + XX(CLUSTER_BAD_SCHEDULING, "Bad cluster.schedulingPolicy: {0}") \ + XX(CONSOLE_EXPECTS_READABLE, "Console expects a writable stream instance") \ + XX(CONSOLE_NO_SUCH_LABEL, "No such label: {0}") \ + XX(CRYPTO_NO_KEY, "No key provided to sign") \ + XX(CRYPTO_BAD_FORMAT, "Bad format: {0}") \ + XX(CRYPTO_CANNOT_CHANGE_ENCODING, "Cannot change encoding") \ + XX(DGRAM_UNIX_DGRAM_NOT_SUPPORTED, \ + "'unix_dgram' type sockets are no longer supported") \ + XX(DGRAM_BAD_SOCKET_TYPE, \ + "Bad socket type specified. Valid types are: udp4, udp6") \ + XX(SOCKET_BOUND, "Socket is already bound") \ + XX(DGRAM_SEND_BAD_ARGUMENTS, \ + "send() takes 'offset' and 'length' the second and third arguments") \ + XX(DGRAM_MUST_SEND_TO_ADDRESS_PORT, \ + "{0} sockets must send to port, address") \ + XX(DGRAM_OFFSET_TOO_LOW, "Offset should be >= 0") \ + XX(DGRAM_OFFSET_TOO_HIGH, "Offset into buffer is too large") \ + XX(DGRAM_LENGTH_TOO_LOW, "Length should be >= 0") \ + XX(DGRAM_OFFSET_LENGTH_OVER, "Offset + length beyond buffer length") \ + XX(PORT_OUT_OF_RANGE, "Port should be > 0 and < 65536") \ + XX(REQUIRED_ARGUMENT, "{0} argument must be specified") \ + XX(NOT_RUNNING, "Not running") \ + XX(DNS_HINTS_VALUE, "'{0}' must be a valid flag") \ + XX(DNS_FAMILY_VALUE, "'{0}' must be 4 or 6") \ + XX(DNS_INVALID_ARGUMENTS, "Invalid arguments") \ + XX(DNS_VALID_ID, "'{0}' argument must be a valid IP address'") \ + XX(DNS_UNKNOWN_TYPE, "Unknown type '{0}'") \ + XX(DNS_MALFORMED_IP, "IP address is not properly formatted: {0}") \ + XX(DNS_FAILED_TO_SET_SERVERS, "c-ares failed to set servers: {0} [{1}]") \ + XX(ARGUMENT_POSITIVE_NUMBER, "'{0}' must be a positive number") \ + XX(UNCAUGHT_UNSPECIFIED_ERROR, "Uncaught, unspecified 'error' event") \ + XX(UNCAUGHT_UNSPECIFIED_ERROR2, "Uncaught, unspecified 'error' event ({0})")\ + XX(EVENT_MEMORY_LEAK, \ + "warning: possible EventEmitter memory " \ + "leak detected. {0} {1} listeners added." \ + "Use emitter.setMaxListeners() to increase limit.") \ + XX(ARGUMENT_STRING_OR_OBJECT, "'{0}' argument must be a string or object") \ + XX(PATH_NULL_BYTES, "'{0}' must be a string without null bytes") \ + XX(FS_SIZE_TOO_LARGE, \ + "File size is greater than possible Buffer: 0x{0} bytes") \ + XX(FS_UNKNOWN_FLAG, "Unknown file open flag: {0}") \ + XX(FS_MALFORMED_TIME, "Cannot parse time: {0}") \ + XX(FS_OPTION_LESS_THAN, "'{0}' option must be <= '{1}' option") \ + XX(FS_OPTION_MORE_THAN_0, "'{0}' must be >= zero") \ + XX(FS_INVALID_DATA, "Invalid data") \ + XX(BAD_ARGUMENTS, "Bad arguments") \ + XX(HTTPS_REUSE_SESSION, "reuse session for {0}") \ + XX(HTTPS_EVICTING, "evicting {0}") \ + XX(MODULE_NOT_FOUND, "Cannot find module '{0}'") \ + XX(MODULE_ASSERT_MISSING_PATH, "missing path") \ + XX(MODULE_ASSERT_PATH_STRING, "path must be a string") \ + XX(NET_UNSUPPORTED_FD, "Unsupported fd type: {0}") \ + XX(NET_PEER_ENDED, "This socket has been ended by the other party") \ + XX(NET_INVALID_ADDRESS_TYPE, "Invalid addressType: {0}") \ + XX(ARGUMENT_STRING_OR_NUMBER, "'{0}' argument must be a string or number") \ + XX(NET_INVALID_LISTENER_ARG, "Invalid listen argument: {0}") \ + XX(PUNYCODE_OVERFLOW, "Overflow: input needs wider integers to process") \ + XX(PUNYCODE_NOTBASIC, "Illegal input >= 0x80 (not a basic code point)") \ + XX(PUNYCODE_INVALIDINPUT, "Invalid input") \ + XX(READLINE_CANNOT_SET_COL, \ + "Cannot set cursor row without also setting the column") \ + XX(REPL_OPTIONS_OR_PROMPT_REQUIRED, \ + "An options object, or a prompt string are required") \ + XX(REPL_NPM_OUTSIDE, \ + "npm should be run outside of the node repl, in your normal shell.\n" \ + "(Press Control-D to exit.)") \ + XX(REPL_BLOCK_SCOPED, \ + "Block-scoped declarations (let, const, function, class) " \ + "not yet supported outside strict mode") \ + XX(REPL_EXIT, "(To exit, press ^C again or type .exit)") \ + XX(REPL_INVALID_KEYWORD, "Invalid REPL keyword") \ + XX(REPL_COMMAND_BREAK, "Sometimes you get stuck, this gets you out") \ + XX(REPL_COMMAND_CLEAR_GLOBAL, "Alias for .break") \ + XX(REPL_COMMAND_CLEAR, "Break, and also clear the local context") \ + XX(REPL_COMMAND_CLEAR_MSG, "Clearing context...") \ + XX(REPL_COMMAND_EXIT, "Exit the repl") \ + XX(REPL_COMMAND_HELP, "Show repl options") \ + XX(REPL_COMMAND_SAVE, \ + "Save all evaluated commands in this REPL session to a file") \ + XX(REPL_COMMAND_SESSION_SAVED, "Session saved to:{0}") \ + XX(REPL_COMMAND_SAVE_FAILED, "Failed to save:{0}") \ + XX(REPL_COMMAND_LOAD, "Load JS from a file into the REPL session") \ + XX(REPL_COMMAND_LOAD_FAILED_INVALID, \ + "Failed to load:{0} is not a valid file") \ + XX(REPL_COMMAND_LOAD_FAILED, "Failed to load:{0}") \ + XX(REPL_CANNOT_PARSE_HISTORY, "Could not parse history data in {0}.") \ + XX(REPL_HISTORY_DISABLED, \ + "Persistent history support disabled. Set the " \ + "NODE_REPL_HISTORY environment\nvariable to " \ + "a valid, user-writable path to enable.") \ + XX(REPL_HOME_DIRECTORY, \ + "Error: Could not get the home directory.\n" \ + "REPL session history will not be persisted.") \ + XX(REPL_CANNOT_OPEN_HISTORY, \ + "Error: Could not open history file.\n" \ + "REPL session history will not be persisted.") \ + XX(REPL_HISTORY_SAME_NAME, \ + "The old repl history file has the same name and location as " \ + "the new one i.e., {0} and is empty.\nUsing it as is.") \ + XX(REPL_CONVERTING_HISTORY, \ + "Converting old JSON repl history to line-separated history.\n" \ + "The new repl history file can be found at {0}.") \ + XX(TIMERS_NON_NEGATIVE_FINITE, \ + "'{0}' argument must be a non-negative finite number") \ + XX(TLS_HOSTNAME_NO_MATCH, \ + "Hostname/IP doesn't match certificate's altnames: '{0}'") \ + XX(TLS_UNKNOWN_REASON, "Unknown reason") \ + XX(TLS_HOST_NOT_IN_CERT_LIST, "IP: {0} is not in the cert's list: {1}") \ + XX(TLS_HOST_NOT_IN_CERT_ALTNAMES, \ + "Host: {0} is not in the cert's altnames: {1}") \ + XX(TLS_HOST_NOT_IN_CERT_CN, "Host: {0} is not cert's CN: {1}") \ + XX(TLS_CERT_IS_EMPTY, "Cert is empty") \ + XX(UTIL_INHERITS_CONSTRUCTOR, \ + "The constructor to 'inherits' must not be null or undefined") \ + XX(UTIL_INHERITS_SUPER_CONSTRUCTOR, \ + "The super constructor to 'inherits' must not be null or undefined") \ + XX(UTIL_INHERITS_SUPER_CONSTRUCTOR_PROTOTYPE, \ + "The super constructor to 'inherits' must have a prototype") \ + XX(UTIL_LOCAL, "Local") \ + XX(ZLIB_RANGE_ERROR, \ + "Cannot create final Buffer. It would be larger than 0x{0} bytes") \ + XX(ZLIB_STRING_OR_BUFFER, "'{0}' must be a string or Buffer") \ + XX(ZLIB_INVALID_FLUSH_FLAG, "Invalid flush flag: {0}") \ + XX(ZLIB_INVALID_CHUNK_SIZE, "Invalid chunk size: {0}") \ + XX(ZLIB_INVALID_WINDOWBITS, "Invalid windowBits: {0}") \ + XX(ZLIB_INVALID_COMPRESSION, "Invalid compression level: {0}") \ + XX(ZLIB_INVALID_MEMLEVEL, "Invalid memLevel: {0}") \ + XX(ZLIB_INVALID_STRATEGY, "Invalid strategy: {0}") \ + XX(ZLIB_INVALID_DICTIONARY, \ + "Invalid dictionary: it should be a Buffer instance") \ + XX(ZLIB_ASSERT_BINDING_CLOSED, "zlib binding closed") \ + XX(ZLIB_INVALID_INPUT, "invalid input") \ + XX(ZLIB_ASSERT_HAVE_GO_DOWN, "have should not go down") \ + XX(SOCKET_LIST_SLAVE_CLOSED, "Slave closed before reply") \ + XX(V8_VALID_ISOLATE_FILE, \ + "Please provide a valid isolate file as the final argument.") \ + XX(V8_UNABLE_TO_READ_VERSION, "Unable to read v8-version from log file.") \ + XX(V8_VERSION_DIFFERENT, \ + "Testing v8 version different from logging version") \ + XX(HTTP_AGENT_DEBUG_FREE_SOCKET, "have free socket") \ + XX(HTTP_AGENT_DEBUG_CALL_ONSOCKET, "call onSocket") \ + XX(HTTP_AGENT_DEBUG_WAIT_FOR_SOCKET, "wait for socket") \ + XX(HTTP_AGENT_DEBUG_SOCKETS, "sockets {0} {1}") \ + XX(HTTP_AGENT_DEBUG_CLIENT_CLOSE, "CLIENT socket onClose") \ + XX(HTTP_AGENT_DEBUG_CLIENT_REMOVE, "CLIENT socket onRemove") \ + XX(HTTP_AGENT_DEBUG_DESTROYED, "removeSocket {0} destroyed {1}") \ + XX(HTTP_AGENT_DEBUG_MAKE_SOCKET, \ + "removeSocket, have a request, make a socket") \ + XX(HTTP_AGENT_DEBUG_ONFREE, "agent.on(free) {0}") \ + XX(HTTP_AGENT_DEBUG_CREATE_CONNECTION, "createConnection {0} {1}") \ + XX(HTTP_CLIENT_DEBUG_CLIENT_CREATE, "CLIENT use net.createConnection {0}") \ + XX(HTTP_CLIENT_DEBUG_SOCKET_CLOSE, "HTTP socket close") \ + XX(HTTP_CLIENT_DEBUG_SOCKET_ERROR, "SOCKET ERROR {0} {1}") \ + XX(HTTP_CLIENT_DEBUG_SOCKET_ERROR_FREE, \ + "SOCKET ERROR on FREE socket {0} {1}") \ + XX(HTTP_CLIENT_DEBUG_PARSE_ERROR, "parse error") \ + XX(HTTP_CLIENT_DEBUG_SETTING_RESDOMAIN, "setting \"res.domain\"") \ + XX(HTTP_CLIENT_DEBUG_INCOMING_RESPONSE, "AGENT incoming response!") \ + XX(HTTP_CLIENT_DEBUG_ISHEAD, "AGENT isHeadResponse {0}") \ + XX(HTTP_CLIENT_DEBUG_SOCKET_DESTROYSOON, "AGENT socket.destroySoon()") \ + XX(HTTP_CLIENT_DEBUG_KEEPALIVE, "AGENT socket keep-alive") \ + XX(HTTP_OUTGOING_DEBUG_NOT_USE_CHUNKED, \ + "{0} response should not use chunked encoding, closing connection.") \ + XX(HTTP_OUTGOING_DEBUG_BOTH_REMOVED, \ + "Both Content-Length and Transfer-Encoding are removed") \ + XX(HTTP_OUTGOING_DEBUG_IGNORING_WRITE, \ + "This type of response MUST NOT have a body. Ignoring write() calls.") \ + XX(HTTP_OUTGOING_DEBUG_WRITE_RET, "write ret = {0}") \ + XX(HTTP_OUTGOING_DEBUG_IGNORING_END_DATA, \ + "This type of response MUST NOT have a body. " \ + "Ignoring data passed to end().") \ + XX(HTTP_SERVER_DEBUG_SOCKET_CLOSE, "server socket close") \ + XX(HTTP_SERVER_DEBUG_NEW_CONNECTION, "SERVER new http connection") \ + XX(HTTP_SERVER_DEBUG_SOCKETONDATA, "SERVER socketOnData {0}") \ + XX(HTTP_SERVER_DEBUG_SOCKETONPARSEREXECUTE, \ + "SERVER socketOnParserExecute {0}") \ + XX(HTTP_SERVER_DEBUG_UPGRADE_OR_CONNECT, "SERVER upgrade or connect {0}") \ + XX(HTTP_SERVER_DEBUG_HAVE_LISTENER, "SERVER have listener for {0}") \ + XX(HTTP_SERVER_DEBUG_PAUSE_PARSER, "pause parser") \ + XX(STREAM_READABLE_DEBUG_NEED_READABLE, "need readable {0}") \ + XX(STREAM_READABLE_DEBUG_LESS_THAN_WATERMARK, \ + "length less than watermark {0}") \ + XX(STREAM_READABLE_DEBUG_READING_OR_ENDED, "reading or ended {0}") \ + XX(STREAM_READABLE_DEBUG_DO_READ, "do read") \ + XX(STREAM_READABLE_DEBUG_EMIT_READABLE_ARG, "emit readable {0}") \ + XX(STREAM_READABLE_DEBUG_EMIT_READABLE, "emit readable") \ + XX(STREAM_READABLE_DEBUG_MAYBE_READMORE, "maybeReadMore read 0") \ + XX(STREAM_READABLE_DEBUG_FALSE_WRITE, "false write response, pause {0}") \ + XX(STREAM_READABLE_DEBUG_PIPE_RESUME, "pipe resume") \ + XX(STREAM_READABLE_DEBUG_READABLE_NEXTTICK, "readable nexttick read 0") \ + XX(STREAM_READABLE_DEBUG_RESUME_READ, "resume read 0") \ + XX(TIMERS_DEBUG_CALLBACK, "timeout callback {0}") \ + XX(TIMERS_DEBUG_NOW, "now: {0}") \ + XX(TIMERS_DEBUG_LIST_WAIT, "{0} list wait because diff is {1}") \ + XX(TIMERS_DEBUG_LIST_EMPTY, "{0} list empty") \ + XX(TIMERS_DEBUG_REUSE_HIT, "reuse hit") \ + XX(TIMERS_DEBUG_UNENROLL, "unenroll: list empty") \ + XX(TIMERS_DEBUG_UNREFTIMER_TIMEOUT, "unreftimer firing timeout") \ + XX(TIMERS_DEBUG_UNREFTIMER_FIRED, "unrefTimer fired") \ + XX(TIMERS_DEBUG_UNREFTIMER_RESCHED, "unrefTimer rescheduled") \ + XX(TIMERS_DEBUG_UNREFLIST_EMPTY, "unrefList is empty") \ + XX(TIMERS_DEBUG_UNREFLIST_INIT, "unrefList initialized") \ + XX(TIMERS_DEBUG_UNREFTIMER_INIT, "unrefTimer initialized") \ + XX(TIMERS_DEBUG_UNREFTIMER_SCHED, "unrefTimer scheduled") \ + XX(TIMERS_DEBUG_UNREFLIST_APPEND, "unrefList append to end") \ + XX(REPL_DEBUG_PARSE_ERROR, "parse error {0} {1}") \ + XX(REPL_DEBUG_NOT_RECOVERABLE, "not recoverable, send to domain") \ + XX(REPL_DEBUG_DOMAIN_ERROR, "domain error") \ + XX(REPL_DEBUG_LINE, "line {0}") \ + XX(REPL_DEBUG_EVAL, "eval {0}") \ + XX(REPL_DEBUG_FINISH, "finish {0} {1}") \ + XX(NET_DEBUG_ONCONNECTION, "onconnection") \ + XX(NET_DEBUG_SERVER_EMITCLOSEIFDRAINED, "SERVER _emitCloseIfDrained") \ + XX(NET_DEBUG_SERVER_HANDLE, "SERVER handle? {0} connections? {1}") \ + XX(NET_DEBUG_SERVER_EMITCLOSE, "SERVER: emit close") \ + XX(NET_DEBUG_CREATECONNECTION, "createConnection {0}") \ + XX(NET_DEBUG_NOTYETCONNECTED, "osF: not yet connected") \ + XX(NET_DEBUG_ONSOCKETFINISH, "onSocketFinish") \ + XX(NET_DEBUG_OSFENDED, "oSF: ended, destroy {0}") \ + XX(NET_DEBUG_OFSNOTENDED, "oSF: not ended, call shutdown()") \ + XX(NET_DEBUG_AFTERSHUTDOWN, "afterShutdown destroyed={0} {1}") \ + XX(NET_DEBUG_READABLESTATEENDED, "readableState ended, destroying") \ + XX(NET_DEBUG_ONSOCKET_END, "onSocketEnd {0}") \ + XX(NET_DEBUG_SOCKETLISTEN, "socket.listen") \ + XX(NET_DEBUG_ONTIMEOUT, "_onTimeout") \ + XX(NET_DEBUG_READ, "_read") \ + XX(NET_DEBUG_READWAITFORCON, "_read wait for connection") \ + XX(NET_DEBUG_READSTART, "Socket._read readStart") \ + XX(NET_DEBUG_DESTROY, "destroy") \ + XX(NET_DEBUG_ALREADYDESTROYED, "already destroyed, fire error callbacks") \ + XX(NET_DEBUG_CLOSE, "close") \ + XX(NET_DEBUG_CLOSEHANDLE, "close handle") \ + XX(NET_DEBUG_EMITCLOSE, "emit close") \ + XX(NET_DEBUG_HASSERVER, "has server") \ + XX(NET_DEBUG_DESTROY_ERR, "destroy {0}") \ + XX(NET_DEBUG_ONREAD, "onread") \ + XX(NET_DEBUG_GOTDATA, "got data") \ + XX(NET_DEBUG_READSTOP, "readStop") \ + XX(NET_DEBUG_NODATA_KEEPREADING, "not any data, keep waiting") \ + XX(NET_DEBUG_EOF, "EOF") \ + XX(NET_DEBUG_AFTERWRITE, "afterWrite {0}") \ + XX(NET_DEBUG_AFTERWRITE_DESTROYED, "afterWrite destroyed") \ + XX(NET_DEBUG_WRITEFAILURE, "write failure {0}") \ + XX(NET_DEBUG_AFTERWRITECB, "afterWrite call cb") \ + XX(NET_DEBUG_BINDING, "binding to localAddress: {0} and localPort: {1}") \ + XX(NET_DEBUG_PIPE, "pipe {0} {1}") \ + XX(NET_DEBUG_CONNECT_FINDHOST, "connect: find host {0}") \ + XX(NET_DEBUG_CONNECT_DNSOPTS, "connect: dns options {0}") \ + XX(NET_DEBUG_AFTERCONNECT, "afterConnect") \ + XX(NET_DEBUG_INVALIDFD, "listen invalid fd={0}:{1}") \ + XX(NET_DEBUG_BINDTO, "bind to {0}") \ + XX(NET_DEBUG_LISTEN2, "listen2 {0} {1} {2} {3} {4}") \ + XX(NET_DEBUG_LISTEN2_HAVE_HANDLE, "_listen2: have a handle already") \ + XX(NET_DEBUG_LISTEN2_CREATE_HANDLE, "_listen2: create a handle") \ + XX(CHILD_PROCESS_DEBUG_SPAWN, "spawn {0} {1}") \ + XX(CHILD_PROCESS_DEBUG_SPAWNSYNC, "spawnSync {0} {1}") \ + XX(MODULE_DEBUG_RELATIVE_REQUESTED, \ + "RELATIVE: requested: {0} set ID to: {1} from {2}") \ + XX(MODULE_DEBUG_LOAD_REQUEST, \ + "Module._load REQUEST {0} parent: {1}") \ + XX(MODULE_DEBUG_LOAD_NATIVE, "load native module {0}") \ + XX(MODULE_DEBUG_LOOKING_FOR, "looking for {0} in {1}") \ + XX(MODULE_DEBUG_LOAD, "load {0} for module {1}") \ + XX(HTTPS_DEBUG_CREATECONNECTION, "createConnection {0}") \ + XX(TLS_LEGACY_DEBUG_ONFINISH, "{0}.onfinish") \ + XX(TLS_LEGACY_DEBUG_ONEND, "cleartext.onend") \ + XX(TLS_LEGACY_DEBUG_WRITE, "{0}.write called with {1} bytes") \ + XX(TLS_LEGACY_DEBUG_WRITE_SUCCEED, "{0}.write succeed with {1} bytes") \ + XX(TLS_LEGACY_DEBUG_CLEARTEXT_WRITE_QUEUE_FULL, \ + "cleartext.write queue is full") \ + XX(TLS_LEGACY_DEBUG_WRITE_QUEUE_BYTES, "{0}.write queued with {1} bytes") \ + XX(TLS_LEGACY_DEBUG_READ_CALLED, "{0}.read called with {1} bytes") \ + XX(TLS_LEGACY_DEBUG_READ_SUCCEED, "{0}.read succeed with {1} bytes") \ + XX(TLS_LEGACY_DEBUG_OUTEND, "{0}.sslOutEnd") \ + XX(TLS_LEGACY_DEBUG_END, "{0}.end") \ + XX(TLS_LEGACY_DEBUG_DESTROYSOON, "{0}.destroySoon") \ + XX(TLS_LEGACY_DEBUG_DESTROY, "{0}.destroy") \ + XX(TLS_LEGACY_DEBUG_SECUREPAIR_DESTROY, "SecurePair.destroy") \ + XX(TLS_DEBUG_ONHANDSHAKESTART, "onhandshakestart") \ + XX(TLS_DEBUG_ONHANDSHAKEONE, "onhandshakedone") \ + XX(TLS_DEBUG_SECURE_ESTABLISHED, "secure established") \ + XX(TLS_DEBUG_START, "start") \ + XX(STREAM_WRAP_DEBUG_CLOSE, "close") \ + XX(STREAM_WRAP_DEBUG_DATA, "data {0}") \ + XX(STREAM_WRAP_DEBUG_END, "end") \ + XX(STREAM_READABLE_DEBUG_WRAPPED_END, "wrapped end") \ + XX(STREAM_READABLE_DEBUG_WRAPPED_DATA, "wrapped data") \ + XX(STREAM_READABLE_DEBUG_WRAPPED_READ, "wrapped _read {0}") \ + XX(STREAM_READABLE_DEBUG_READ, "read {0}") \ + XX(STREAM_READABLE_DEBUG_PIPE_COUNT, "pipe count={0} opts={1}") \ + XX(STREAM_READABLE_DEBUG_ONUNPIPE, "onunpipe") \ + XX(STREAM_READABLE_DEBUG_ONEND, "onend") \ + XX(STREAM_READABLE_DEBUG_CLEANUP, "cleanup") \ + XX(STREAM_READABLE_DEBUG_ONDATA, "ondata") \ + XX(STREAM_READABLE_DEBUG_ONERROR, "onerror") \ + XX(STREAM_READABLE_DEBUG_ONFINISH, "onfinish") \ + XX(STREAM_READABLE_DEBUG_UNPIPE, "unpipe") \ + XX(STREAM_READABLE_DEBUG_PIPEONDRAIN, "pipeOnDrain {0}") \ + XX(STREAM_READABLE_DEBUG_RESUME, "resume") \ + XX(STREAM_READABLE_DEBUG_PAUSE, "pause") \ + XX(STREAM_READABLE_DEBUG_FLOW, "flow") \ + XX(HTTP_OUTGOING_FLUSH_DEPRECATE, \ + NODE_DEPRECATE_MESSAGE("OutgoingMessage.flush", "flushHeaders")) \ + XX(LINKLIST_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("_linklist module", "a userland alternative")) \ + XX(UTIL_PRINT_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("util.print", "console.log")) \ + XX(UTIL_PUTS_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("util.puts", "console.log")) \ + XX(UTIL_DEBUG_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("util.debug", "console.error")) \ + XX(UTIL_ERROR_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("util.error", "console.error")) \ + XX(STREAM_WRITABLE_WRITABLESTATE_BUFFER_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("_writableState.buffer", \ + "_writableState.getBuffer")) \ + XX(BUFFER_GET_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("Buffer.get", "array indices")) \ + XX(BUFFER_SET_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("Buffer.set", "array indices")) \ + XX(BUFFER_WRITE_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE( \ + "Buffer.write(string, encoding, offset, length)", \ + "write(string[, offset[, length]][, encoding])")) \ + XX(CHILD_PROCESS_CUSTOMFDS_DEPRECATE, \ + NODE_DEPRECATE_MESSAGE("options.customFds", "options.stdio")) \ + XX(CRYPTO_CREATECREDENTIALS_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("crypto.createCredentials", \ + "tls.createSecureContext")) \ + XX(CRYPTO_CREDENTIALS_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("crypto.Credentials", "tls.createSecureContext")) \ + XX(HTTP_CLIENT_DEPRECRATED, "http.Client is deprecated.") \ + XX(HTTP_CREATECLIENT_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("http.createClient", "http.request")) \ + XX(MODULE_REQUIRE_OUTSIDE_WARNING, \ + "warning: require(\'.\') resolved outside the package " \ + "directory. This functionality is deprecated and will be removed soon.") \ + XX(MODULE_REQUIREREPL_DEPRECATED, "Module.requireRepl is deprecated.") \ + XX(NET_SERVER_CONNECTIONS_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("Server.connections", "Server.getConnections")) \ + XX(NET_SERVER_CONNECTIONS_DEPRECATED_SET, \ + "Server.connections property is deprecated.") \ + XX(NET_SERVER_LISTENFD_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("Server.listenFD", \ + "Server.listen({fd: })")) \ + XX(OS_GETNETWORKINTERFACES_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("os.getNetworkInterfaces", \ + "os.networkInterfaces")) \ + XX(READLINE_CODEPOINT_DEPRECATED, \ + NODE_DEPRECATE_MESSAGE("readline.codePointAt", \ + "String.prototype.codePointAt")) \ + XX(READLINE_GETSTRINGWIDTH_DEPRECATED, \ + "getStringWidth is deprecated and will be removed.") \ + XX(READLINE_ISFULLWIDTHCODEPOINT_DEPRECATED, \ + "isFullWidthCodePoint is deprecated and will be removed.") \ + XX(READLINE_STRIPVTCONTROLCHARACTERS_DEPRECATED, \ + "stripVTControlCharacters is deprecated and will be removed.") \ + XX(SYS_DEPRECATED, NODE_DEPRECATE_MESSAGE("sys", "util")) \ + + +#endif // SRC_NODE_MESSAGES_SRC_H_ diff --git a/src/messages/messages.cc b/src/messages/messages.cc new file mode 100644 index 00000000000000..1349b1211ae9fe --- /dev/null +++ b/src/messages/messages.cc @@ -0,0 +1,28 @@ +#include "messages.h" + +// const char* nodemsgid(int key) { +// switch(key) { +// #define ID_NODE_MESSAGES(id, _) case SRC_MSG_ ## id: return #id; +// NODE_SRC_MESSAGES(ID_NODE_MESSAGES) +// #undef ID_NODE_MESSAGES +// default: return NODE_MESSAGE_UNKNOWN; +// } +// } +// +// const char* nodemsgstr(int key) { +// switch(key) { +// #define STR_NODE_MESSAGES(id, msg) case SRC_MSG_ ## id: return msg; +// NODE_SRC_MESSAGES(STR_NODE_MESSAGES) +// #undef STR_NODE_MESSAGES +// default: return NODE_MESSAGE_UNKNOWN; +// } +// } +// +// const char* nodeerrstr(int key) { +// switch(key) { +// #define STR_NODE_MESSAGES(id, msg) case SRC_MSG_ ## id: return msg " (" #id ")"; +// NODE_SRC_MESSAGES(STR_NODE_MESSAGES) +// #undef STR_NODE_MESSAGES +// default: return NODE_MESSAGE_UNKNOWN; +// } +// } diff --git a/src/messages/messages.h b/src/messages/messages.h new file mode 100644 index 00000000000000..47fcb2e183e550 --- /dev/null +++ b/src/messages/messages.h @@ -0,0 +1,29 @@ +#ifndef SRC_NODE_MESSAGES_API_H_ +#define SRC_NODE_MESSAGES_API_H_ + +// TODO(jasnell): Allow other locales to be swapped in based on build config +#include "en/messages.h" + +typedef enum { +#define DEF_NODE_MESSAGES(id,_) MSG_ ## id, + NODE_MESSAGES(DEF_NODE_MESSAGES) +#undef DEF_NODE_MESSAGES + MSG_UNKNOWN +} node_messages; + +// /** +// * Returns the const char* message identifier associated with the message key +// **/ +// const char* nodemsgid(int key); +// +// /** +// * Returns the text of the message associated with the message key +// **/ +// const char* nodemsgstr(int key); +// +// /** +// * Returns the text of the message with the err key appended +// **/ +// const char * nodeerrstr(int key); +// +#endif // SRC_NODE_MESSAGES_API_H_ diff --git a/src/node.cc b/src/node.cc index 29127fbfc620ca..460bb5e5643afc 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1,5 +1,6 @@ #include "node.h" #include "node_buffer.h" +#include "node_messages.h" #include "node_constants.h" #include "node_file.h" #include "node_http_parser.h" @@ -737,6 +738,41 @@ void ThrowUVException(v8::Isolate* isolate, ->ThrowUVException(errorno, syscall, message, path, dest); } +Local I18NError(Isolate* isolate, + const char* key, + const char* msg) { + Environment* env = Environment::GetCurrent(isolate); + Local message = OneByteString(env->isolate(), msg); + Local skey = OneByteString(env->isolate(), key); + Local e = Exception::Error(message); + Local obj = e->ToObject(env->isolate()); + obj->Set(OneByteString(env->isolate(), "key"), skey); + return e; +} + +Local I18NRangeError(Isolate* isolate, + const char* key, + const char* msg) { + Environment* env = Environment::GetCurrent(isolate); + Local message = OneByteString(env->isolate(), msg); + Local skey = OneByteString(env->isolate(), key); + Local e = Exception::RangeError(message); + Local obj = e->ToObject(env->isolate()); + obj->Set(OneByteString(env->isolate(), "key"), skey); + return e; +} + +Local I18NTypeError(Isolate* isolate, + const char* key, + const char* msg) { + Environment* env = Environment::GetCurrent(isolate); + Local message = OneByteString(env->isolate(), msg); + Local skey = OneByteString(env->isolate(), key); + Local e = Exception::TypeError(message); + Local obj = e->ToObject(env->isolate()); + obj->Set(OneByteString(env->isolate(), "key"), skey); + return e; +} Local ErrnoException(Isolate* isolate, int errorno, @@ -1027,7 +1063,7 @@ void SetupDomainUse(const FunctionCallbackInfo& args) { process_object->Get(tick_callback_function_key).As(); if (!tick_callback_function->IsFunction()) { - fprintf(stderr, "process._tickDomainCallback assigned to non-function\n"); + fprintf(stderr, STR_PROCESS_TICKDOMAIN_NONFUNCTION); ABORT(); } @@ -1381,8 +1417,7 @@ ssize_t DecodeBytes(Isolate* isolate, HandleScope scope(isolate); if (val->IsArray()) { - fprintf(stderr, "'raw' encoding (array of integers) has been removed. " - "Use 'binary'.\n"); + fprintf(stderr, STR_RAW_ENCODING_REMOVED); UNREACHABLE(); return -1; } @@ -2241,7 +2276,7 @@ void DLOpen(const FunctionCallbackInfo& args) { char errmsg[1024]; snprintf(errmsg, sizeof(errmsg), - "Module version mismatch. Expected %d, got %d.", + STR_MODULE_VERSION_MISMATCH, NODE_MODULE_VERSION, mp->nm_version); // NOTE: `mp` is allocated inside of the shared library's memory, calling @@ -2368,7 +2403,7 @@ static void Binding(const FunctionCallbackInfo& args) { // Append a string to process.moduleLoadList char buf[1024]; - snprintf(buf, sizeof(buf), "Binding %s", *module_v); + snprintf(buf, sizeof(buf), STR_BINDING, *module_v); Local modules = env->module_load_list_array(); uint32_t l = modules->Length(); @@ -2384,6 +2419,10 @@ static void Binding(const FunctionCallbackInfo& args) { mod->nm_context_register_func(exports, unused, env->context(), mod->nm_priv); cache->Set(module, exports); + } else if (!strcmp(*module_v, "messages")) { + exports = Object::New(env->isolate()); + DefineMessages(env, exports); + cache->Set(module, exports); } else if (!strcmp(*module_v, "constants")) { exports = Object::New(env->isolate()); DefineConstants(exports); @@ -2396,7 +2435,7 @@ static void Binding(const FunctionCallbackInfo& args) { char errmsg[1024]; snprintf(errmsg, sizeof(errmsg), - "No such module: %s", + STR_NO_SUCH_MODULE, *module_v); return env->ThrowError(errmsg); } @@ -2422,7 +2461,7 @@ static void LinkedBinding(const FunctionCallbackInfo& args) { char errmsg[1024]; snprintf(errmsg, sizeof(errmsg), - "No such module was linked: %s", + STR_NO_SUCH_MODULE_LINKED, *module_v); return env->ThrowError(errmsg); } @@ -3228,7 +3267,7 @@ static bool ParseDebugOpt(const char* arg) { if (port != nullptr) { debug_port = atoi(port); if (debug_port < 1024 || debug_port > 65535) { - fprintf(stderr, "Debug port must be in range 1024 to 65535.\n"); + fprintf(stderr, STR_DEBUGPORT_OUTOFRANGE); PrintHelp(); exit(12); } @@ -3238,57 +3277,7 @@ static bool ParseDebugOpt(const char* arg) { } static void PrintHelp() { - printf("Usage: node [options] [ -e script | script.js ] [arguments] \n" - " node debug script.js [arguments] \n" - "\n" - "Options:\n" - " -v, --version print Node.js version\n" - " -e, --eval script evaluate script\n" - " -p, --print evaluate script and print result\n" - " -c, --check syntax check script without executing\n" - " -i, --interactive always enter the REPL even if stdin\n" - " does not appear to be a terminal\n" - " -r, --require module to preload (option can be repeated)\n" - " --no-deprecation silence deprecation warnings\n" - " --throw-deprecation throw an exception anytime a deprecated " - "function is used\n" - " --trace-deprecation show stack traces on deprecations\n" - " --trace-sync-io show stack trace when use of sync IO\n" - " is detected after the first tick\n" - " --track-heap-objects track heap object allocations for heap " - "snapshots\n" - " --prof-process process v8 profiler output generated\n" - " using --prof\n" - " --v8-options print v8 command line options\n" -#if HAVE_OPENSSL - " --tls-cipher-list=val use an alternative default TLS cipher list\n" -#endif -#if defined(NODE_HAVE_I18N_SUPPORT) - " --icu-data-dir=dir set ICU data load path to dir\n" - " (overrides NODE_ICU_DATA)\n" -#if !defined(NODE_HAVE_SMALL_ICU) - " note: linked-in ICU data is\n" - " present.\n" -#endif -#endif - "\n" - "Environment variables:\n" -#ifdef _WIN32 - "NODE_PATH ';'-separated list of directories\n" -#else - "NODE_PATH ':'-separated list of directories\n" -#endif - " prefixed to the module search path.\n" - "NODE_DISABLE_COLORS set to 1 to disable colors in the REPL\n" -#if defined(NODE_HAVE_I18N_SUPPORT) - "NODE_ICU_DATA data path for ICU (Intl object) data\n" -#if !defined(NODE_HAVE_SMALL_ICU) - " (will extend linked-in data)\n" -#endif -#endif - "NODE_REPL_HISTORY path to the persistent REPL history file\n" - "\n" - "Documentation can be found at https://nodejs.org/\n"); + printf(STR_NODEHELP); } @@ -3356,7 +3345,7 @@ static void ParseArgs(int* argc, args_consumed += 1; eval_string = argv[index + 1]; if (eval_string == nullptr) { - fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg); + fprintf(stderr, STR_REQUIRES_ARGUMENT, argv[0], arg); exit(9); } } else if ((index + 1 < nargs) && @@ -3373,7 +3362,7 @@ static void ParseArgs(int* argc, strcmp(arg, "-r") == 0) { const char* module = argv[index + 1]; if (module == nullptr) { - fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg); + fprintf(stderr, STR_REQUIRES_ARGUMENT, argv[0], arg); exit(9); } args_consumed += 1; @@ -3464,7 +3453,7 @@ static void StartDebug(Environment* env, bool wait) { DispatchMessagesDebugAgentCallback); debugger_running = env->debugger_agent()->Start(debug_port, wait); if (debugger_running == false) { - fprintf(stderr, "Starting debugger on port %d failed\n", debug_port); + fprintf(stderr, STR_START_DEBUGGER_FAIL, debug_port); fflush(stderr); return; } @@ -3513,7 +3502,7 @@ static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle) { } while (isolate == nullptr); if (debugger_running == false) { - fprintf(stderr, "Starting debugger agent.\n"); + fprintf(stderr, STR_START_DEBUGGER_AGENT); HandleScope scope(isolate); Environment* env = Environment::GetCurrent(isolate); @@ -3874,7 +3863,7 @@ void Init(int* argc, // Anything that's still in v8_argv is not a V8 or a node option. for (int i = 1; i < v8_argc; i++) { - fprintf(stderr, "%s: bad option: %s\n", argv[0], v8_argv[i]); + fprintf(stderr, "%s: " STR_BAD_OPTION ": %s\n", argv[0], v8_argv[i]); } delete[] v8_argv; v8_argv = nullptr; diff --git a/src/node.h b/src/node.h index ef1f629d20aa0e..0fe59c6a9ccbbf 100644 --- a/src/node.h +++ b/src/node.h @@ -95,6 +95,15 @@ NODE_EXTERN v8::Local UVException(v8::Isolate* isolate, const char* message, const char* path, const char* dest); +NODE_EXTERN v8::Local I18NRangeError(v8::Isolate* isolate, + const char* key, + const char* message); +NODE_EXTERN v8::Local I18NTypeError(v8::Isolate* isolate, + const char* key, + const char* message); +NODE_EXTERN v8::Local I18NError(v8::Isolate* isolate, + const char* key, + const char* message); NODE_DEPRECATED("Use ErrnoException(isolate, ...)", inline v8::Local ErrnoException( @@ -156,6 +165,8 @@ NODE_EXTERN v8::Local MakeCallback( #include "node_internals.h" #endif +#include "messages/messages.h" + #include #include @@ -175,7 +186,6 @@ typedef intptr_t ssize_t; # include // size_t, ssize_t #endif // _WIN32 - namespace node { NODE_EXTERN extern bool no_deprecation; diff --git a/src/node.js b/src/node.js index 6e25edd8a057c6..eb6d903f834819 100644 --- a/src/node.js +++ b/src/node.js @@ -198,7 +198,9 @@ ]; } - throw new TypeError('process.hrtime() only accepts an Array tuple'); + // process.hrtime() only accepts an Array tuple + const I18N = NativeModule.require('internal/messages'); + throw new I18N.TypeError(I18N.HRTIME_ARRAY); } return [ @@ -278,8 +280,11 @@ var assert; startup.processAssert = function() { + const I18N = NativeModule.require('internal/messages'); assert = process.assert = function(x, msg) { - if (!x) throw new Error(msg || 'assertion error'); + if (!x) { + throw msg ? new Error(msg) : new I18N.Error(I18N.ASSERTION_ERROR); + } }; }; @@ -305,6 +310,7 @@ var addPendingUnhandledRejection; var hasBeenNotifiedProperty = new WeakMap(); startup.processNextTick = function() { + const I18N = NativeModule.require('internal/messages'); var nextTickQueue = []; var pendingUnhandledRejections = []; var microtasksScheduled = false; @@ -508,8 +514,9 @@ } function nextTick(callback) { - if (typeof callback !== 'function') - throw new TypeError('callback is not a function'); + if (typeof callback !== 'function') { + throw new I18N.TypeError(I18N.FUNCTION_REQUIRED, 'callback'); + } // on the way out, don't bother. it won't get fired anyway. if (process._exiting) return; @@ -550,6 +557,7 @@ }; startup.processPromises = function() { + const I18N = NativeModule.require('internal/messages'); var promiseRejectEvent = process._promiseRejectEvent; function unhandledRejection(promise, reason) { @@ -575,8 +583,11 @@ unhandledRejection(promise, reason); else if (event === promiseRejectEvent.handled) rejectionHandled(promise); - else - NativeModule.require('assert').fail('unexpected PromiseRejectEvent'); + else { + // unexpected PromiseRejectEvent + NativeModule.require('assert').fail(I18N(I18N.UNEXPECTED, + 'PromiseRejectEvent')); + } }); }; @@ -616,6 +627,7 @@ } function createWritableStdioStream(fd) { + const I18N = NativeModule.require('internal/messages'); var stream; var tty_wrap = process.binding('tty_wrap'); @@ -647,7 +659,8 @@ default: // Probably an error on in uv_guess_handle() - throw new Error('Implement me. Unknown stream file type!'); + // Unknown stream file type!' + throw new I18N.Error(I18N.UNKNOWN_STREAM_FILE_TYPE); } // For supporting legacy API we put the FD here. @@ -659,13 +672,15 @@ } startup.processStdio = function() { + const I18N = NativeModule.require('internal/messages'); var stdin, stdout, stderr; process.__defineGetter__('stdout', function() { if (stdout) return stdout; stdout = createWritableStdioStream(1); stdout.destroy = stdout.destroySoon = function(er) { - er = er || new Error('process.stdout cannot be closed.'); + // process.stdout cannot be closed. + er = er || new I18N.Error(I18N.CLOSE_STDOUT); stdout.emit('error', er); }; if (stdout.isTTY) { @@ -680,7 +695,8 @@ if (stderr) return stderr; stderr = createWritableStdioStream(2); stderr.destroy = stderr.destroySoon = function(er) { - er = er || new Error('process.stderr cannot be closed.'); + // process.stderr cannot be closed + er = er || new I18N.Error(I18N.CLOSE_STDERR); stderr.emit('error', er); }; if (stderr.isTTY) { @@ -739,7 +755,8 @@ default: // Probably an error on in uv_guess_handle() - throw new Error('Implement me. Unknown stdin file type!'); + // Unknown stdin file type! + throw new I18N.Error(I18N.UNKNOWN_STDIN_FILE_TYPE); } // For supporting legacy API we put the FD here. @@ -774,7 +791,7 @@ }; startup.processKillAndExit = function() { - + const I18N = NativeModule.require('internal/messages'); process.exit = function(code) { if (code || code === 0) process.exitCode = code; @@ -790,7 +807,8 @@ var err; if (pid != (pid | 0)) { - throw new TypeError('invalid pid'); + // invalid pid + throw new I18N.TypeError(I18N.INVALID_PID); } // preserve null signal @@ -802,7 +820,8 @@ sig.slice(0, 3) === 'SIG') { err = process._kill(pid, startup.lazyConstants()[sig]); } else { - throw new Error('Unknown signal: ' + sig); + // unknown signal + throw new I18N.Error(I18N.UNKNOWN_SIGNAL, sig); } } @@ -926,7 +945,12 @@ } if (!NativeModule.exists(id)) { - throw new Error('No such native module ' + id); + // no such native module .. we cannot use internal/messages here... + const I18N = process.binding('messages'); + const msg = I18N.msg(I18N.UNKNOWN_NATIVE_MODULE); + const err = new Error(`${msg.msg} ${id}`); + err.key = msg.id; + throw err; } process.moduleLoadList.push('NativeModule ' + id); diff --git a/src/node_buffer.cc b/src/node_buffer.cc index dca75a817b7414..06e6f63aad4cf2 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -17,15 +17,15 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define CHECK_NOT_OOB(r) \ - do { \ - if (!(r)) return env->ThrowRangeError("out of range index"); \ +#define CHECK_NOT_OOB(r) \ + do { \ + if (!(r)) return THROWI18NRANGEERROR(env, INDEX_OUT_OF_RANGE); \ } while (0) -#define THROW_AND_RETURN_UNLESS_BUFFER(env, obj) \ - do { \ - if (!HasInstance(obj)) \ - return env->ThrowTypeError("argument should be a Buffer"); \ +#define THROW_AND_RETURN_UNLESS_BUFFER(env, obj) \ + do { \ + if (!HasInstance(obj)) \ + return THROWI18NTYPEERROR(env, ARGUMENT_BUFFER); \ } while (0) #define SPREAD_ARG(val, name) \ @@ -427,13 +427,13 @@ void CreateFromString(const FunctionCallbackInfo& args) { void CreateFromArrayBuffer(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsArrayBuffer()) - return env->ThrowTypeError("argument is not an ArrayBuffer"); + return THROWI18NTYPEERROR(env, ARGUMENT_ARRAYBUFFER); Local ab = args[0].As(); Local ui = Uint8Array::New(ab, 0, ab->ByteLength()); Maybe mb = ui->SetPrototype(env->context(), env->buffer_prototype_object()); if (!mb.FromMaybe(false)) - return env->ThrowError("Unable to set Object prototype"); + return THROWI18NERROR(env, UNABLE_TO_SET_PROTOTYPE); args.GetReturnValue().Set(ui); } @@ -555,7 +555,7 @@ void Copy(const FunctionCallbackInfo &args) { return args.GetReturnValue().Set(0); if (source_start > ts_obj_length) - return env->ThrowRangeError("out of range index"); + return THROWI18NRANGEERROR(env, INDEX_OUT_OF_RANGE); if (source_end - source_start > target_length - target_start) source_end = source_start + target_length - target_start; @@ -570,7 +570,8 @@ void Copy(const FunctionCallbackInfo &args) { void Fill(const FunctionCallbackInfo& args) { - THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]); + Environment* env = Environment::GetCurrent(args); + THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]); SPREAD_ARG(args[0], ts_obj); size_t start = args[2]->Uint32Value(); @@ -618,12 +619,12 @@ void StringWrite(const FunctionCallbackInfo& args) { SPREAD_ARG(args.This(), ts_obj); if (!args[0]->IsString()) - return env->ThrowTypeError("Argument must be a string"); + return THROWI18NTYPEERROR(env, ARGUMENT_STRING); Local str = args[0]->ToString(env->isolate()); if (encoding == HEX && str->Length() % 2 != 0) - return env->ThrowTypeError("Invalid hex string"); + return THROWI18NTYPEERROR(env, INVALID_HEX); size_t offset; size_t max_length; @@ -637,7 +638,7 @@ void StringWrite(const FunctionCallbackInfo& args) { return args.GetReturnValue().Set(0); if (offset >= ts_obj_length) - return env->ThrowRangeError("Offset is out of bounds"); + return THROWI18NRANGEERROR(env, OFFSET_OUTOFBOUNDS); uint32_t written = StringBytes::Write(env->isolate(), ts_obj_data + offset, @@ -691,7 +692,8 @@ static inline void Swizzle(char* start, unsigned int len) { template void ReadFloatGeneric(const FunctionCallbackInfo& args) { - THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]); + Environment* env = Environment::GetCurrent(args); + THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]); SPREAD_ARG(args[0], ts_obj); uint32_t offset = args[1]->Uint32Value(); @@ -842,8 +844,8 @@ void IndexOfString(const FunctionCallbackInfo& args) { enum encoding enc = ParseEncoding(args.GetIsolate(), args[3], UTF8); - - THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]); + Environment* env = Environment::GetCurrent(args); + THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]); SPREAD_ARG(args[0], ts_obj); Local needle = args[1].As(); @@ -943,8 +945,8 @@ void IndexOfBuffer(const FunctionCallbackInfo& args) { enum encoding enc = ParseEncoding(args.GetIsolate(), args[3], UTF8); - - THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]); + Environment* env = Environment::GetCurrent(args); + THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]); SPREAD_ARG(args[0], ts_obj); SPREAD_ARG(args[1], buf); @@ -1005,8 +1007,8 @@ void IndexOfBuffer(const FunctionCallbackInfo& args) { void IndexOfNumber(const FunctionCallbackInfo& args) { ASSERT(args[1]->IsNumber()); ASSERT(args[2]->IsNumber()); - - THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]); + Environment* env = Environment::GetCurrent(args); + THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]); SPREAD_ARG(args[0], ts_obj); uint32_t needle = args[1]->Uint32Value(); diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 6675e2d8a08f70..62b4d9a9664b05 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -282,7 +282,7 @@ class ContextifyContext { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsObject()) { - return env->ThrowTypeError("sandbox argument must be an object."); + return THROWI18NTYPEERROR(env, SANDBOX_OBJECT); } Local sandbox = args[0].As(); @@ -312,8 +312,7 @@ class ContextifyContext { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsObject()) { - env->ThrowTypeError("sandbox must be an object"); - return; + return THROWI18NTYPEERROR(env, SANDBOX_OBJECT); } Local sandbox = args[0].As(); @@ -495,7 +494,7 @@ class ContextifyScript : public BaseObject { Environment* env = Environment::GetCurrent(args); if (!args.IsConstructCall()) { - return env->ThrowError("Must call vm.Script as a constructor."); + return THROWI18NERROR(env, VMSCRIPT_AS_CONSTRUCTOR); } ContextifyScript* contextify_script = @@ -559,8 +558,7 @@ class ContextifyScript : public BaseObject { // Assemble arguments if (!args[0]->IsObject()) { - return env->ThrowTypeError( - "contextifiedSandbox argument must be an object."); + return THROWI18NTYPEERROR(env, CONTEXTIFIED_MUST_BE_OBJECT); } Local sandbox = args[0].As(); @@ -579,8 +577,7 @@ class ContextifyScript : public BaseObject { ContextifyContext::ContextFromContextifiedSandbox(env->isolate(), sandbox); if (contextify_context == nullptr) { - return env->ThrowTypeError( - "sandbox argument must have been converted to a context."); + return THROWI18NTYPEERROR(env, SANDBOX_ARGUMENT_CONVERSION); } if (contextify_context->context().IsEmpty()) @@ -607,12 +604,12 @@ class ContextifyScript : public BaseObject { static int64_t GetTimeoutArg(const FunctionCallbackInfo& args, const int i) { + Environment* env = Environment::GetCurrent(args); if (args[i]->IsUndefined() || args[i]->IsString()) { return -1; } if (!args[i]->IsObject()) { - Environment::ThrowTypeError(args.GetIsolate(), - "options must be an object"); + THROWI18NTYPEERROR(env, OPTIONS_OBJECT); return -1; } @@ -624,8 +621,7 @@ class ContextifyScript : public BaseObject { int64_t timeout = value->IntegerValue(); if (timeout <= 0) { - Environment::ThrowRangeError(args.GetIsolate(), - "timeout must be a positive number"); + THROWI18NRANGEERROR(env, TIMEOUT_POSITIVE); return -1; } return timeout; @@ -634,12 +630,12 @@ class ContextifyScript : public BaseObject { static bool GetDisplayErrorsArg(const FunctionCallbackInfo& args, const int i) { + Environment* env = Environment::GetCurrent(args); if (args[i]->IsUndefined() || args[i]->IsString()) { return true; } if (!args[i]->IsObject()) { - Environment::ThrowTypeError(args.GetIsolate(), - "options must be an object"); + THROWI18NTYPEERROR(env, OPTIONS_OBJECT); return false; } @@ -653,6 +649,7 @@ class ContextifyScript : public BaseObject { static Local GetFilenameArg(const FunctionCallbackInfo& args, const int i) { + Environment* env = Environment::GetCurrent(args); Local defaultFilename = FIXED_ONE_BYTE_STRING(args.GetIsolate(), "evalmachine."); @@ -663,8 +660,7 @@ class ContextifyScript : public BaseObject { return args[i].As(); } if (!args[i]->IsObject()) { - Environment::ThrowTypeError(args.GetIsolate(), - "options must be an object"); + THROWI18NTYPEERROR(env, OPTIONS_OBJECT); return Local(); } @@ -716,8 +712,7 @@ class ContextifyScript : public BaseObject { const FunctionCallbackInfo& args, TryCatch& try_catch) { if (!ContextifyScript::InstanceOf(env, args.Holder())) { - env->ThrowTypeError( - "Script methods can only be called on script instances."); + THROWI18NTYPEERROR(env, CANNOT_CALL_SCRIPT_METHODS); return false; } @@ -736,7 +731,7 @@ class ContextifyScript : public BaseObject { if (try_catch.HasCaught() && try_catch.HasTerminated()) { V8::CancelTerminateExecution(env->isolate()); - env->ThrowError("Script execution timed out."); + THROWI18NERROR(env, SCRIPT_EXECUTION_TIMEDOUT); try_catch.ReThrow(); return false; } diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 35a0687b9f95ec..176ef6ef254101 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -36,14 +36,14 @@ #define THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(val) \ do { \ if (!Buffer::HasInstance(val) && !val->IsString()) { \ - return env->ThrowTypeError("Not a string or buffer"); \ + return THROWI18NTYPEERROR(env, NOT_STRING_BUFFER); \ } \ } while (0) #define THROW_AND_RETURN_IF_NOT_BUFFER(val) \ do { \ if (!Buffer::HasInstance(val)) { \ - return env->ThrowTypeError("Not a buffer"); \ + return THROWI18NTYPEERROR(env, NOT_BUFFER); \ } \ } while (0) @@ -347,17 +347,17 @@ void SecureContext::Init(const FunctionCallbackInfo& args) { // protocols are supported unless explicitly disabled (which we do below // for SSLv2 and SSLv3.) if (strcmp(*sslmethod, "SSLv2_method") == 0) { - return env->ThrowError("SSLv2 methods disabled"); + return THROWI18NERROR(env, SSLV2_METHODS_DISABLED); } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) { - return env->ThrowError("SSLv2 methods disabled"); + return THROWI18NERROR(env, SSLV2_METHODS_DISABLED); } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) { - return env->ThrowError("SSLv2 methods disabled"); + return THROWI18NERROR(env, SSLV2_METHODS_DISABLED); } else if (strcmp(*sslmethod, "SSLv3_method") == 0) { - return env->ThrowError("SSLv3 methods disabled"); + return THROWI18NERROR(env, SSLV3_METHODS_DISABLED); } else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) { - return env->ThrowError("SSLv3 methods disabled"); + return THROWI18NERROR(env, SSLV3_METHODS_DISABLED); } else if (strcmp(*sslmethod, "SSLv3_client_method") == 0) { - return env->ThrowError("SSLv3 methods disabled"); + return THROWI18NERROR(env, SSLV3_METHODS_DISABLED); } else if (strcmp(*sslmethod, "SSLv23_method") == 0) { method = SSLv23_method(); } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) { @@ -383,7 +383,7 @@ void SecureContext::Init(const FunctionCallbackInfo& args) { } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) { method = TLSv1_2_client_method(); } else { - return env->ThrowError("Unknown method"); + return THROWI18NERROR(env, UNKNOWN_METHOD); } } @@ -445,10 +445,10 @@ void SecureContext::SetKey(const FunctionCallbackInfo& args) { unsigned int len = args.Length(); if (len != 1 && len != 2) { - return env->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); } if (len == 2 && !args[1]->IsString()) { - return env->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); } BIO *bio = LoadBIO(env, args[0]); @@ -466,7 +466,7 @@ void SecureContext::SetKey(const FunctionCallbackInfo& args) { BIO_free_all(bio); unsigned long err = ERR_get_error(); if (!err) { - return env->ThrowError("PEM_read_bio_PrivateKey"); + return THROWI18NERROR(env, PEM_READ_BIO); } return ThrowCryptoError(env, err); } @@ -478,7 +478,7 @@ void SecureContext::SetKey(const FunctionCallbackInfo& args) { if (!rv) { unsigned long err = ERR_get_error(); if (!err) - return env->ThrowError("SSL_CTX_use_PrivateKey"); + return THROWI18NERROR(env, CTX_USE_PRIVATEKEY); return ThrowCryptoError(env, err); } } @@ -647,7 +647,7 @@ void SecureContext::SetCert(const FunctionCallbackInfo& args) { SecureContext* sc = Unwrap(args.Holder()); if (args.Length() != 1) { - return env->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); } BIO* bio = LoadBIO(env, args[0]); @@ -674,7 +674,7 @@ void SecureContext::SetCert(const FunctionCallbackInfo& args) { if (!rv) { unsigned long err = ERR_get_error(); if (!err) { - return env->ThrowError("SSL_CTX_use_certificate_chain"); + return THROWI18NERROR(env, CTX_USE_CERT_CHAIN); } return ThrowCryptoError(env, err); } @@ -690,7 +690,7 @@ void SecureContext::AddCACert(const FunctionCallbackInfo& args) { (void) &clear_error_on_return; // Silence compiler warning. if (args.Length() != 1) { - return env->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); } if (!sc->ca_store_) { @@ -722,7 +722,7 @@ void SecureContext::AddCRL(const FunctionCallbackInfo& args) { SecureContext* sc = Unwrap(args.Holder()); if (args.Length() != 1) { - return env->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); } ClearErrorOnReturn clear_error_on_return; @@ -788,11 +788,12 @@ void SecureContext::AddRootCerts(const FunctionCallbackInfo& args) { void SecureContext::SetCiphers(const FunctionCallbackInfo& args) { SecureContext* sc = Unwrap(args.Holder()); + Environment* env = sc->env(); ClearErrorOnReturn clear_error_on_return; (void) &clear_error_on_return; // Silence compiler warning. if (args.Length() != 1 || !args[0]->IsString()) { - return sc->env()->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); } const node::Utf8Value ciphers(args.GetIsolate(), args[0]); @@ -805,19 +806,19 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo& args) { Environment* env = sc->env(); if (args.Length() != 1 || !args[0]->IsString()) - return env->ThrowTypeError("First argument should be a string"); + return THROWI18NTYPEERROR(env, FIRST_ARGUMENT_STRING); node::Utf8Value curve(env->isolate(), args[0]); int nid = OBJ_sn2nid(*curve); if (nid == NID_undef) - return env->ThrowTypeError("First argument should be a valid curve name"); + return THROWI18NTYPEERROR(env, INVALID_CURVE_NAME); EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid); if (ecdh == nullptr) - return env->ThrowTypeError("First argument should be a valid curve name"); + return THROWI18NTYPEERROR(env, INVALID_CURVE_NAME); SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE); SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh); @@ -835,7 +836,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { // Auto DH is not supported in openssl 1.0.1, so dhparam needs // to be specifed explicitly if (args.Length() != 1) - return env->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); // Invalid dhparam is silently discarded and DHE is no longer used. BIO* bio = LoadBIO(env, args[0]); @@ -850,10 +851,10 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { const int size = BN_num_bits(dh->p); if (size < 1024) { - return env->ThrowError("DH parameter is less than 1024 bits"); + return THROWI18NERROR(env, SMALL_DH_PARAMETER); } else if (size < 2048) { args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING( - env->isolate(), "WARNING: DH parameter is less than 2048 bits")); + env->isolate(), STR_WARN_SMALL_DH)); } SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_DH_USE); @@ -861,15 +862,16 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { DH_free(dh); if (!r) - return env->ThrowTypeError("Error setting temp DH parameter"); + return THROWI18NTYPEERROR(env, SET_DH_ERROR); } void SecureContext::SetOptions(const FunctionCallbackInfo& args) { SecureContext* sc = Unwrap(args.Holder()); + Environment* env = sc->env(); if (args.Length() != 1 || !args[0]->IntegerValue()) { - return sc->env()->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); } SSL_CTX_set_options(sc->ctx_, static_cast(args[0]->IntegerValue())); @@ -879,9 +881,10 @@ void SecureContext::SetOptions(const FunctionCallbackInfo& args) { void SecureContext::SetSessionIdContext( const FunctionCallbackInfo& args) { SecureContext* sc = Unwrap(args.Holder()); + Environment* env = sc->env(); if (args.Length() != 1 || !args[0]->IsString()) { - return sc->env()->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); } const node::Utf8Value sessionIdContext(args.GetIsolate(), args[0]); @@ -900,7 +903,7 @@ void SecureContext::SetSessionIdContext( bio = BIO_new(BIO_s_mem()); if (bio == nullptr) { message = FIXED_ONE_BYTE_STRING(args.GetIsolate(), - "SSL_CTX_set_session_id_context error"); + STR_CTX_SET_SESSION_ID_ERR); } else { ERR_print_errors(bio); BIO_get_mem_ptr(bio, &mem); @@ -914,9 +917,10 @@ void SecureContext::SetSessionIdContext( void SecureContext::SetSessionTimeout(const FunctionCallbackInfo& args) { SecureContext* sc = Unwrap(args.Holder()); + Environment* env = sc->env(); if (args.Length() != 1 || !args[0]->IsInt32()) { - return sc->env()->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); } int32_t sessionTimeout = args[0]->Int32Value(); @@ -947,12 +951,12 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { (void) &clear_error_on_return; // Silence compiler warning. if (args.Length() < 1) { - return env->ThrowTypeError("Bad parameter"); + return THROWI18NTYPEERROR(env, BAD_PARAMETER); } in = LoadBIO(env, args[0]); if (in == nullptr) { - return env->ThrowError("Unable to load BIO"); + return THROWI18NERROR(env, UNABLE_TO_LOAD_BIO); } if (args.Length() >= 2) { @@ -1012,7 +1016,8 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo& args) { if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_, Buffer::Data(buff), Buffer::Length(buff)) != 1) { - return wrap->env()->ThrowError("Failed to fetch tls ticket keys"); + Environment* env = wrap->env(); + return THROWI18NERROR(env, FAILED_FETCH_TLS_TICKET); } args.GetReturnValue().Set(buff); @@ -1027,13 +1032,13 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo& args) { if (args.Length() < 1 || !Buffer::HasInstance(args[0]) || Buffer::Length(args[0]) != 48) { - return wrap->env()->ThrowTypeError("Bad argument"); + return THROWI18NTYPEERROR(wrap->env(), BAD_ARGUMENT); } if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_, Buffer::Data(args[0]), Buffer::Length(args[0])) != 1) { - return wrap->env()->ThrowError("Failed to fetch tls ticket keys"); + return THROWI18NERROR(wrap->env(), FAILED_FETCH_TLS_TICKET); } args.GetReturnValue().Set(true); @@ -1659,7 +1664,7 @@ void SSLWrap::SetSession(const FunctionCallbackInfo& args) { if (args.Length() < 1 || (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) { - return env->ThrowTypeError("Bad argument"); + return THROWI18NTYPEERROR(env, BAD_ARGUMENT); } THROW_AND_RETURN_IF_NOT_BUFFER(args[0]); @@ -1679,7 +1684,7 @@ void SSLWrap::SetSession(const FunctionCallbackInfo& args) { SSL_SESSION_free(sess); if (!r) - return env->ThrowError("SSL_set_session error"); + return THROWI18NERROR(env, SSL_SET_SESSION_ERROR); } @@ -1783,8 +1788,9 @@ void SSLWrap::SetOCSPResponse( HandleScope scope(args.GetIsolate()); Base* w = Unwrap(args.Holder()); - if (args.Length() < 1 || !Buffer::HasInstance(args[0])) - return w->env()->ThrowTypeError("Must give a Buffer as first argument"); + if (args.Length() < 1 || !Buffer::HasInstance(args[0])) { + return THROWI18NTYPEERROR(w->env(), FIRST_ARGUMENT_BUFFER); + } w->ocsp_response_.Reset(args.GetIsolate(), args[0].As()); #endif // NODE__HAVE_TLSEXT_STATUS_CB @@ -2073,7 +2079,7 @@ void SSLWrap::SetNPNProtocols(const FunctionCallbackInfo& args) { Environment* env = w->env(); if (args.Length() < 1 || !Buffer::HasInstance(args[0])) - return env->ThrowTypeError("Must give a Buffer as first argument"); + return THROWI18NTYPEERROR(env, FIRST_ARGUMENT_BUFFER); Local npn_buffer = Local::New(env->isolate(), args[0]); bool r = w->object()->SetHiddenValue(env->npn_buffer_string(), npn_buffer); @@ -2154,7 +2160,7 @@ void SSLWrap::SetALPNProtocols( Base* w = Unwrap(args.Holder()); Environment* env = w->env(); if (args.Length() < 1 || !Buffer::HasInstance(args[0])) - return env->ThrowTypeError("Must give a Buffer as first argument"); + return THROWI18NTYPEERROR(env, FIRST_ARGUMENT_BUFFER); if (w->is_client()) { const unsigned char* alpn_protos = @@ -2316,7 +2322,7 @@ void SSLWrap::CertCbDone(const FunctionCallbackInfo& args) { if (!rv) { unsigned long err = ERR_get_error(); if (!err) - return env->ThrowError("CertCbDone"); + return THROWI18NERROR(env, CERTCBDONE); return ThrowCryptoError(env, err); } } else { @@ -2715,8 +2721,7 @@ void Connection::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1 || !args[0]->IsObject()) { - env->ThrowError("First argument must be a tls module SecureContext"); - return; + return THROWI18NERROR(env, FIRST_ARGUMENT_SECURECONTEXT); } SecureContext* sc = Unwrap(args[0]->ToObject(env->isolate())); @@ -2811,11 +2816,11 @@ void Connection::EncIn(const FunctionCallbackInfo& args) { Environment* env = conn->env(); if (args.Length() < 3) { - return env->ThrowTypeError("Takes 3 parameters"); + return THROWI18NTYPEERROR(env, TAKES_THREE_ARGS); } if (!Buffer::HasInstance(args[0])) { - return env->ThrowTypeError("Second argument should be a buffer"); + return THROWI18NTYPEERROR(env, SECOND_ARGUMENT_BUFFER); } char* buffer_data = Buffer::Data(args[0]); @@ -2825,7 +2830,7 @@ void Connection::EncIn(const FunctionCallbackInfo& args) { size_t len = args[2]->Int32Value(); if (!Buffer::IsWithinBounds(off, len, buffer_length)) - return env->ThrowError("off + len > buffer.length"); + return THROWI18NERROR(env, OFF_LEN_BUFLEN); int bytes_written; char* data = buffer_data + off; @@ -2860,11 +2865,11 @@ void Connection::ClearOut(const FunctionCallbackInfo& args) { Environment* env = conn->env(); if (args.Length() < 3) { - return env->ThrowTypeError("Takes 3 parameters"); + return THROWI18NERROR(env, TAKES_THREE_ARGS); } if (!Buffer::HasInstance(args[0])) { - return env->ThrowTypeError("Second argument should be a buffer"); + return THROWI18NTYPEERROR(env, SECOND_ARGUMENT_BUFFER); } char* buffer_data = Buffer::Data(args[0]); @@ -2874,7 +2879,7 @@ void Connection::ClearOut(const FunctionCallbackInfo& args) { size_t len = args[2]->Int32Value(); if (!Buffer::IsWithinBounds(off, len, buffer_length)) - return env->ThrowError("off + len > buffer.length"); + return THROWI18NERROR(env, OFF_LEN_BUFLEN); if (!SSL_is_init_finished(conn->ssl_)) { int rv; @@ -2928,11 +2933,11 @@ void Connection::EncOut(const FunctionCallbackInfo& args) { Environment* env = conn->env(); if (args.Length() < 3) { - return env->ThrowTypeError("Takes 3 parameters"); + return THROWI18NTYPEERROR(env, TAKES_THREE_ARGS); } if (!Buffer::HasInstance(args[0])) { - return env->ThrowTypeError("Second argument should be a buffer"); + return THROWI18NTYPEERROR(env, SECOND_ARGUMENT_BUFFER); } char* buffer_data = Buffer::Data(args[0]); @@ -2942,7 +2947,7 @@ void Connection::EncOut(const FunctionCallbackInfo& args) { size_t len = args[2]->Int32Value(); if (!Buffer::IsWithinBounds(off, len, buffer_length)) - return env->ThrowError("off + len > buffer.length"); + return THROWI18NERROR(env, OFF_LEN_BUFLEN); int bytes_read = BIO_read(conn->bio_write_, buffer_data + off, len); @@ -2958,11 +2963,11 @@ void Connection::ClearIn(const FunctionCallbackInfo& args) { Environment* env = conn->env(); if (args.Length() < 3) { - return env->ThrowTypeError("Takes 3 parameters"); + return THROWI18NTYPEERROR(env, TAKES_THREE_ARGS); } if (!Buffer::HasInstance(args[0])) { - return env->ThrowTypeError("Second argument should be a buffer"); + return THROWI18NTYPEERROR(env, SECOND_ARGUMENT_BUFFER); } char* buffer_data = Buffer::Data(args[0]); @@ -2972,7 +2977,7 @@ void Connection::ClearIn(const FunctionCallbackInfo& args) { size_t len = args[2]->Int32Value(); if (!Buffer::IsWithinBounds(off, len, buffer_length)) - return env->ThrowError("off + len > buffer.length"); + return THROWI18NERROR(env, OFF_LEN_BUFLEN); if (!SSL_is_init_finished(conn->ssl_)) { int rv; @@ -3057,7 +3062,7 @@ void Connection::SetSNICallback(const FunctionCallbackInfo& args) { Environment* env = conn->env(); if (args.Length() < 1 || !args[0]->IsFunction()) { - return env->ThrowError("Must give a Function as first argument"); + return THROWI18NERROR(env, FIRST_ARGUMENT_FUNCTION); } Local obj = Object::New(env->isolate()); @@ -3100,14 +3105,13 @@ void CipherBase::Init(const char* cipher_type, HandleScope scope(env()->isolate()); #ifdef NODE_FIPS_MODE - return env()->ThrowError( - "crypto.createCipher() is not supported in FIPS mode."); + return THROWI18NERROR(env, CRYPTO_CREATECIPHER_NOT_SUPPORTED); #endif // NODE_FIPS_MODE CHECK_EQ(cipher_, nullptr); cipher_ = EVP_get_cipherbyname(cipher_type); if (cipher_ == nullptr) { - return env()->ThrowError("Unknown cipher"); + return THROWI18NERROR(env(), UNKNOWN_CIPHER); } unsigned char key[EVP_MAX_KEY_LENGTH]; @@ -3127,7 +3131,7 @@ void CipherBase::Init(const char* cipher_type, EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt); if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) { EVP_CIPHER_CTX_cleanup(&ctx_); - return env()->ThrowError("Invalid key length"); + return THROWI18NERROR(env(), INVALID_KEYLEN); } EVP_CipherInit_ex(&ctx_, @@ -3145,7 +3149,7 @@ void CipherBase::Init(const FunctionCallbackInfo& args) { if (args.Length() < 2 || !(args[0]->IsString() && Buffer::HasInstance(args[1]))) { - return cipher->env()->ThrowError("Must give cipher-type, key"); + return THROWI18NERROR(cipher->env(), MUST_GIVE_CIPHER_TYPE); } const node::Utf8Value cipher_type(args.GetIsolate(), args[0]); @@ -3164,21 +3168,21 @@ void CipherBase::InitIv(const char* cipher_type, cipher_ = EVP_get_cipherbyname(cipher_type); if (cipher_ == nullptr) { - return env()->ThrowError("Unknown cipher"); + return THROWI18NERROR(env(), UNKNOWN_CIPHER); } /* OpenSSL versions up to 0.9.8l failed to return the correct iv_length (0) for ECB ciphers */ if (EVP_CIPHER_iv_length(cipher_) != iv_len && !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) { - return env()->ThrowError("Invalid IV length"); + return THROWI18NERROR(env(), INVALID_IVLEN); } EVP_CIPHER_CTX_init(&ctx_); const bool encrypt = (kind_ == kCipher); EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt); if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) { EVP_CIPHER_CTX_cleanup(&ctx_); - return env()->ThrowError("Invalid key length"); + return THROWI18NERROR(env(), INVALID_KEYLEN); } EVP_CipherInit_ex(&ctx_, @@ -3196,7 +3200,7 @@ void CipherBase::InitIv(const FunctionCallbackInfo& args) { Environment* env = cipher->env(); if (args.Length() < 3 || !args[0]->IsString()) { - return env->ThrowError("Must give cipher-type, key, and iv as argument"); + return THROWI18NERROR(env, MUST_GIVE_CIPHER_TYPE_KEY_IV); } THROW_AND_RETURN_IF_NOT_BUFFER(args[1]); @@ -3243,7 +3247,7 @@ void CipherBase::GetAuthTag(const FunctionCallbackInfo& args) { Local buf = Buffer::New(env, out, out_len).ToLocalChecked(); args.GetReturnValue().Set(buf); } else { - env->ThrowError("Attempting to get auth tag in unsupported state"); + THROWI18NERROR(env, CANNOT_GET_AUTH_TAG); } } @@ -3264,12 +3268,12 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo& args) { Local buf = args[0].As(); if (!buf->IsObject() || !Buffer::HasInstance(buf)) - return env->ThrowTypeError("Argument must be a Buffer"); + return THROWI18NTYPEERROR(env, ARGUMENT_BUFFER); CipherBase* cipher = Unwrap(args.Holder()); if (!cipher->SetAuthTag(Buffer::Data(buf), Buffer::Length(buf))) - env->ThrowError("Attempting to set auth tag in unsupported state"); + THROWI18NERROR(env, CANNOT_SET_AUTH_TAG); } @@ -3296,7 +3300,7 @@ void CipherBase::SetAAD(const FunctionCallbackInfo& args) { CipherBase* cipher = Unwrap(args.Holder()); if (!cipher->SetAAD(Buffer::Data(args[0]), Buffer::Length(args[0]))) - env->ThrowError("Attempting to set AAD in unsupported state"); + THROWI18NERROR(env, CANNOT_SET_AAD); } @@ -3354,7 +3358,7 @@ void CipherBase::Update(const FunctionCallbackInfo& args) { delete[] out; return ThrowCryptoError(env, ERR_get_error(), - "Trying to add data in unsupported state"); + STR_CANNOT_ADD_DATA); } CHECK(out != nullptr || out_len == 0); @@ -3425,8 +3429,8 @@ void CipherBase::Final(const FunctionCallbackInfo& args) { out_len = 0; if (!r) { const char* msg = cipher->IsAuthenticatedMode() ? - "Unsupported state or unable to authenticate data" : - "Unsupported state"; + STR_UNSUPPORTED_STATE_UNABLE_TO_AUTH : + STR_UNSUPOPORTED_STATE; return ThrowCryptoError(env, ERR_get_error(), @@ -3468,7 +3472,7 @@ void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) { CHECK_EQ(md_, nullptr); md_ = EVP_get_digestbyname(hash_type); if (md_ == nullptr) { - return env()->ThrowError("Unknown message digest"); + return THROWI18NERROR(env(), UNKNOWN_MESSAGE_DIGEST); } HMAC_CTX_init(&ctx_); int result = 0; @@ -3489,7 +3493,7 @@ void Hmac::HmacInit(const FunctionCallbackInfo& args) { Environment* env = hmac->env(); if (args.Length() < 2 || !args[0]->IsString()) { - return env->ThrowError("Must give hashtype string, key as arguments"); + return THROWI18NERROR(env, MUST_GIVE_HASHTYPE); } THROW_AND_RETURN_IF_NOT_BUFFER(args[1]); @@ -3530,7 +3534,7 @@ void Hmac::HmacUpdate(const FunctionCallbackInfo& args) { } if (!r) { - return env->ThrowTypeError("HmacUpdate fail"); + return THROWI18NTYPEERROR(env, HMACUPDATE_FAIL); } } @@ -3592,7 +3596,7 @@ void Hash::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() == 0 || !args[0]->IsString()) { - return env->ThrowError("Must give hashtype string as argument"); + return THROWI18NERROR(env, MUST_GIVE_HASHTYPE_ARG); } const node::Utf8Value hash_type(env->isolate(), args[0]); @@ -3600,7 +3604,7 @@ void Hash::New(const FunctionCallbackInfo& args) { Hash* hash = new Hash(env, args.This()); if (!hash->HashInit(*hash_type)) { return ThrowCryptoError(env, ERR_get_error(), - "Digest method not supported"); + STR_DIGEST_METHOD_NOT_SUPPORTED); } } @@ -3649,7 +3653,7 @@ void Hash::HashUpdate(const FunctionCallbackInfo& args) { } if (!r) { - return env->ThrowTypeError("HashUpdate fail"); + return THROWI18NTYPEERROR(env, HASHUPDATE_FAIL); } } @@ -3660,7 +3664,7 @@ void Hash::HashDigest(const FunctionCallbackInfo& args) { Hash* hash = Unwrap(args.Holder()); if (!hash->initialised_) { - return env->ThrowError("Not initialized"); + return THROWI18NERROR(env, NOT_INITIALIZED); } enum encoding encoding = BUFFER; @@ -3690,10 +3694,10 @@ void SignBase::CheckThrow(SignBase::Error error) { switch (error) { case kSignUnknownDigest: - return env()->ThrowError("Unknown message digest"); + return THROWI18NERROR(env(), UNKNOWN_MESSAGE_DIGEST); case kSignNotInitialised: - return env()->ThrowError("Not initialised"); + return THROWI18NERROR(env(), NOT_INITIALIZED); case kSignInit: case kSignUpdate: @@ -3705,13 +3709,13 @@ void SignBase::CheckThrow(SignBase::Error error) { return ThrowCryptoError(env(), err); switch (error) { case kSignInit: - return env()->ThrowError("EVP_SignInit_ex failed"); + return THROWI18NERROR(env(), EVP_SIGNINIT_EX_FAIL); case kSignUpdate: - return env()->ThrowError("EVP_SignUpdate failed"); + return THROWI18NERROR(env(), EVP_SIGNUPDATE_FAIL); case kSignPrivateKey: - return env()->ThrowError("PEM_read_bio_PrivateKey failed"); + return THROWI18NERROR(env(), PEM_READ_BIO_PRIVATEKEY_FAIL); case kSignPublicKey: - return env()->ThrowError("PEM_read_bio_PUBKEY failed"); + return THROWI18NERROR(env(), PEM_READ_BIO_PUBKEY_FAIL); default: ABORT(); } @@ -3763,7 +3767,7 @@ void Sign::SignInit(const FunctionCallbackInfo& args) { Sign* sign = Unwrap(args.Holder()); if (args.Length() == 0 || !args[0]->IsString()) { - return sign->env()->ThrowError("Must give signtype string as argument"); + return THROWI18NERROR(sign->env(), MUST_GIVE_SIGNTYPE_ARG); } const node::Utf8Value sign_type(args.GetIsolate(), args[0]); @@ -3963,7 +3967,7 @@ void Verify::VerifyInit(const FunctionCallbackInfo& args) { Verify* verify = Unwrap(args.Holder()); if (args.Length() == 0 || !args[0]->IsString()) { - return verify->env()->ThrowError("Must give verifytype string as argument"); + return THROWI18NERROR(verify->env(), MUST_GIVE_VERIFYTYPE_ARG); } const node::Utf8Value verify_type(args.GetIsolate(), args[0]); @@ -4361,7 +4365,7 @@ void DiffieHellman::DiffieHellmanGroup( DiffieHellman* diffieHellman = new DiffieHellman(env, args.This()); if (args.Length() != 1 || !args[0]->IsString()) { - return env->ThrowError("No group name given"); + return THROWI18NERROR(env, NO_GROUP_NAME); } bool initialized = false; @@ -4378,11 +4382,11 @@ void DiffieHellman::DiffieHellmanGroup( it->gen, it->gen_size); if (!initialized) - env->ThrowError("Initialization failed"); + THROWI18NERROR(env, INIT_FAILED); return; } - env->ThrowError("Unknown group"); + THROWI18NERROR(env, UNKNOWN_GROUP); } @@ -4413,7 +4417,7 @@ void DiffieHellman::New(const FunctionCallbackInfo& args) { } if (!initialized) { - return ThrowCryptoError(env, ERR_get_error(), "Initialization failed"); + return ThrowCryptoError(env, ERR_get_error(), STR_INIT_FAILED); } } @@ -4424,11 +4428,11 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), STR_NOT_INITIALIZED); } if (!DH_generate_key(diffieHellman->dh)) { - return ThrowCryptoError(env, ERR_get_error(), "Key generation failed"); + return ThrowCryptoError(env, ERR_get_error(), STR_KEY_GENERATION_FAIL); } int dataSize = BN_num_bytes(diffieHellman->dh->pub_key); @@ -4447,7 +4451,7 @@ void DiffieHellman::GetPrime(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), STR_NOT_INITIALIZED); } int dataSize = BN_num_bytes(diffieHellman->dh->p); @@ -4465,7 +4469,7 @@ void DiffieHellman::GetGenerator(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), STR_NOT_INITIALIZED); } int dataSize = BN_num_bytes(diffieHellman->dh->g); @@ -4483,11 +4487,11 @@ void DiffieHellman::GetPublicKey(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), STR_NOT_INITIALIZED); } if (diffieHellman->dh->pub_key == nullptr) { - return env->ThrowError("No public key - did you forget to generate one?"); + return THROWI18NERROR(env, NO_PUBKEY); } int dataSize = BN_num_bytes(diffieHellman->dh->pub_key); @@ -4506,11 +4510,11 @@ void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), STR_NOT_INITIALIZED); } if (diffieHellman->dh->priv_key == nullptr) { - return env->ThrowError("No private key - did you forget to generate one?"); + return THROWI18NERROR(env, NO_PVTKEY); } int dataSize = BN_num_bytes(diffieHellman->dh->priv_key); @@ -4529,7 +4533,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), STR_NOT_INITIALIZED); } ClearErrorOnReturn clear_error_on_return; @@ -4537,7 +4541,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo& args) { BIGNUM* key = nullptr; if (args.Length() == 0) { - return env->ThrowError("First argument must be other party's public key"); + return THROWI18NERROR(env, FIRST_ARGUMENT_PUBKEY); } else { THROW_AND_RETURN_IF_NOT_BUFFER(args[0]); key = BN_bin2bn( @@ -4562,17 +4566,17 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo& args) { delete[] data; if (!checked) { - return ThrowCryptoError(env, ERR_get_error(), "Invalid Key"); + return ThrowCryptoError(env, ERR_get_error(), STR_INVALID_KEY); } else if (checkResult) { if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) { - return env->ThrowError("Supplied key is too small"); + return THROWI18NERROR(env, SUPPLIED_KEY_SMALL); } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) { - return env->ThrowError("Supplied key is too large"); + return THROWI18NERROR(env, SUPPLIED_KEY_LARGE); } else { - return env->ThrowError("Invalid key"); + return THROWI18NERROR(env, INVALID_KEY); } } else { - return env->ThrowError("Invalid key"); + return THROWI18NERROR(env, INVALID_KEY); } } @@ -4599,11 +4603,11 @@ void DiffieHellman::SetPublicKey(const FunctionCallbackInfo& args) { Environment* env = diffieHellman->env(); if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), STR_NOT_INITIALIZED); } if (args.Length() == 0) { - return env->ThrowError("First argument must be public key"); + return THROWI18NERROR(env, FIRST_ARGUMENT_PUBKEY2); } else { THROW_AND_RETURN_IF_NOT_BUFFER(args[0]); diffieHellman->dh->pub_key = BN_bin2bn( @@ -4618,11 +4622,11 @@ void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo& args) { Environment* env = diffieHellman->env(); if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), STR_NOT_INITIALIZED); } if (args.Length() == 0) { - return env->ThrowError("First argument must be private key"); + return THROWI18NERROR(env, FIRST_ARGUMENT_PVTKEY); } else { THROW_AND_RETURN_IF_NOT_BUFFER(args[0]); diffieHellman->dh->priv_key = BN_bin2bn( @@ -4641,7 +4645,7 @@ void DiffieHellman::VerifyErrorGetter(Local property, if (!diffieHellman->initialised_) return ThrowCryptoError(diffieHellman->env(), ERR_get_error(), - "Not initialized"); + STR_NOT_INITIALIZED); args.GetReturnValue().Set(diffieHellman->verifyError_); } @@ -4684,11 +4688,11 @@ void ECDH::New(const FunctionCallbackInfo& args) { int nid = OBJ_sn2nid(*curve); if (nid == NID_undef) - return env->ThrowTypeError("First argument should be a valid curve name"); + return THROWI18NTYPEERROR(env, INVALID_CURVE_NAME); EC_KEY* key = EC_KEY_new_by_curve_name(nid); if (key == nullptr) - return env->ThrowError("Failed to create EC_KEY using curve name"); + return THROWI18NERROR(env, CREATE_ECKEY_FAIL); new ECDH(env, args.This(), key); } @@ -4700,7 +4704,7 @@ void ECDH::GenerateKeys(const FunctionCallbackInfo& args) { ECDH* ecdh = Unwrap(args.Holder()); if (!EC_KEY_generate_key(ecdh->key_)) - return env->ThrowError("Failed to generate EC_KEY"); + return THROWI18NERROR(env, GENERATE_ECKEY_FAIL); } @@ -4710,7 +4714,7 @@ EC_POINT* ECDH::BufferToPoint(char* data, size_t len) { pub = EC_POINT_new(group_); if (pub == nullptr) { - env()->ThrowError("Failed to allocate EC_POINT for a public key"); + THROWI18NERROR(env(), ALLOCATE_ECPOINT_FAIL); return nullptr; } @@ -4721,7 +4725,7 @@ EC_POINT* ECDH::BufferToPoint(char* data, size_t len) { len, nullptr); if (!r) { - env()->ThrowError("Failed to translate Buffer to a EC_POINT"); + THROWI18NERROR(env(), TRANSLATE_BUFFER_FAIL); goto fatal; } @@ -4741,7 +4745,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo& args) { ECDH* ecdh = Unwrap(args.Holder()); if (!ecdh->IsKeyPairValid()) - return env->ThrowError("Invalid key pair"); + return THROWI18NERROR(env, INVALID_KEYPAIR); EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0]), Buffer::Length(args[0])); @@ -4758,7 +4762,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo& args) { EC_POINT_free(pub); if (!r) { free(out); - return env->ThrowError("Failed to compute ECDH key"); + return THROWI18NERROR(env, COMPUTEECDH_FAIL); } Local buf = Buffer::New(env, out, out_len).ToLocalChecked(); @@ -4776,7 +4780,7 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo& args) { const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_); if (pub == nullptr) - return env->ThrowError("Failed to get ECDH public key"); + return THROWI18NERROR(env, GETECDH_FAIL); int size; point_conversion_form_t form = @@ -4784,7 +4788,7 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo& args) { size = EC_POINT_point2oct(ecdh->group_, pub, form, nullptr, 0, nullptr); if (size == 0) - return env->ThrowError("Failed to get public key length"); + return THROWI18NERROR(env, GET_PUBKEY_FAIL); unsigned char* out = static_cast(malloc(size)); CHECK_NE(out, nullptr); @@ -4792,7 +4796,7 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo& args) { int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr); if (r != size) { free(out); - return env->ThrowError("Failed to get public key"); + return THROWI18NERROR(env, GET_PUBKEY_FAIL2); } Local buf = @@ -4808,7 +4812,7 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo& args) { const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_); if (b == nullptr) - return env->ThrowError("Failed to get ECDH private key"); + return THROWI18NERROR(env, GET_ECDH_PVTKEY_FAIL); int size = BN_num_bytes(b); unsigned char* out = static_cast(malloc(size)); @@ -4816,7 +4820,7 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo& args) { if (size != BN_bn2bin(b, out)) { free(out); - return env->ThrowError("Failed to convert ECDH private key to Buffer"); + return THROWI18NERROR(env, CONVERT_ECDH_PVTKEY_FAIL); } Local buf = @@ -4837,18 +4841,18 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo& args) { Buffer::Length(args[0].As()), nullptr); if (priv == nullptr) - return env->ThrowError("Failed to convert Buffer to BN"); + return THROWI18NERROR(env, CONVERT_BUFFER_BN_FAIL); if (!ecdh->IsKeyValidForCurve(priv)) { BN_free(priv); - return env->ThrowError("Private key is not valid for specified curve."); + return THROWI18NERROR(env, PVTKEY_NOTVALID_CURVE); } int result = EC_KEY_set_private_key(ecdh->key_, priv); BN_free(priv); if (!result) { - return env->ThrowError("Failed to convert BN to a private key"); + return THROWI18NERROR(env, CONVERT_BN_PVTKEY_FAIL); } // To avoid inconsistency, clear the current public key in-case computing @@ -4866,12 +4870,12 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo& args) { if (!EC_POINT_mul(ecdh->group_, pub, priv_key, nullptr, nullptr, nullptr)) { EC_POINT_free(pub); - return env->ThrowError("Failed to generate ECDH public key"); + return THROWI18NERROR(env, GENERATE_ECDH_PUBKEY_FAIL); } if (!EC_KEY_set_public_key(ecdh->key_, pub)) { EC_POINT_free(pub); - return env->ThrowError("Failed to set generated public key"); + return THROWI18NERROR(env, SET_PUBKEY_FAIL); } EC_POINT_free(pub); @@ -4888,7 +4892,7 @@ void ECDH::SetPublicKey(const FunctionCallbackInfo& args) { EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0].As()), Buffer::Length(args[0].As())); if (pub == nullptr) - return env->ThrowError("Failed to convert Buffer to EC_POINT"); + return THROWI18NERROR(env, CONVERT_BUFFER_ECPOINT_FAIL); int r = EC_KEY_set_public_key(ecdh->key_, pub); EC_POINT_free(pub); @@ -5120,24 +5124,24 @@ void PBKDF2(const FunctionCallbackInfo& args) { memcpy(salt, Buffer::Data(args[1]), saltlen); if (!args[2]->IsNumber()) { - type_error = "Iterations not a number"; + type_error = STR_ITERATIONS_NOT_NUMBER; goto err; } iter = args[2]->Int32Value(); if (iter < 0) { - type_error = "Bad iterations"; + type_error = STR_BAD_ITERATIONS; goto err; } if (!args[3]->IsNumber()) { - type_error = "Key length not a number"; + type_error = STR_KEYLEN_NOT_NUMBER; goto err; } keylen = args[3]->NumberValue(); if (keylen < 0 || isnan(keylen) || isinf(keylen)) { - type_error = "Bad key length"; + type_error = STR_BAD_KEYLEN; goto err; } @@ -5145,7 +5149,7 @@ void PBKDF2(const FunctionCallbackInfo& args) { node::Utf8Value digest_name(env->isolate(), args[4]); digest = EVP_get_digestbyname(*digest_name); if (digest == nullptr) { - type_error = "Bad digest name"; + type_error = STR_BAD_DIGEST_NAME; goto err; } } @@ -5278,7 +5282,7 @@ void RandomBytesWork(uv_work_t* work_req) { // don't call this function without a valid HandleScope void RandomBytesCheck(RandomBytesRequest* req, Local argv[2]) { if (req->error()) { - char errmsg[256] = "Operation not supported"; + char errmsg[256] = STR_OPERATION_NOT_SUPPORTED; if (req->error() != static_cast(-1)) ERR_error_string_n(req->error(), errmsg, sizeof errmsg); @@ -5316,12 +5320,12 @@ void RandomBytes(const FunctionCallbackInfo& args) { // maybe allow a buffer to write to? cuts down on object creation // when generating random data in a loop if (!args[0]->IsUint32()) { - return env->ThrowTypeError("size must be a number >= 0"); + return THROWI18NTYPEERROR(env, POSITIVE_NUMBER); } const int64_t size = args[0]->IntegerValue(); if (size < 0 || size > Buffer::kMaxLength) - return env->ThrowRangeError("size is not a valid Smi"); + return THROWI18NRANGEERROR(env, SIZE_NOT_VALID_SMI); Local obj = env->NewInternalFieldObject(); RandomBytesRequest* req = new RandomBytesRequest(env, obj, size); @@ -5356,13 +5360,13 @@ void GetSSLCiphers(const FunctionCallbackInfo& args) { SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method()); if (ctx == nullptr) { - return env->ThrowError("SSL_CTX_new() failed."); + return THROWI18NERROR(env, SSL_CTL_NEW_FAIL); } SSL* ssl = SSL_new(ctx); if (ssl == nullptr) { SSL_CTX_free(ctx); - return env->ThrowError("SSL_new() failed."); + return THROWI18NERROR(env, SSL_NEW_FAIL); } Local arr = Array::New(env->isolate()); @@ -5502,7 +5506,7 @@ void Certificate::VerifySpkac(const FunctionCallbackInfo& args) { bool i = false; if (args.Length() < 1) - return env->ThrowTypeError("Missing argument"); + return THROWI18NTYPEERROR(env, MISSING_ARGUMENT); THROW_AND_RETURN_IF_NOT_BUFFER(args[0]); @@ -5566,7 +5570,7 @@ void Certificate::ExportPublicKey(const FunctionCallbackInfo& args) { Certificate* certificate = Unwrap(args.Holder()); if (args.Length() < 1) - return env->ThrowTypeError("Missing argument"); + return THROWI18NTYPEERROR(env, MISSING_ARGUMENT); THROW_AND_RETURN_IF_NOT_BUFFER(args[0]); @@ -5611,7 +5615,7 @@ void Certificate::ExportChallenge(const FunctionCallbackInfo& args) { Certificate* crt = Unwrap(args.Holder()); if (args.Length() < 1) - return env->ThrowTypeError("Missing argument"); + return THROWI18NTYPEERROR(env, MISSING_ARGUMENT); THROW_AND_RETURN_IF_NOT_BUFFER(args[0]); @@ -5646,7 +5650,7 @@ void InitCryptoOnce() { #ifdef NODE_FIPS_MODE if (!FIPS_mode_set(1)) { int err = ERR_get_error(); - fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(err, NULL)); + fprintf(stderr, STR_OPENSSL_FIPS_FAIL, ERR_error_string(err, NULL)); UNREACHABLE(); } #endif // NODE_FIPS_MODE @@ -5698,7 +5702,7 @@ void SetEngine(const FunctionCallbackInfo& args) { int err = ERR_get_error(); if (err == 0) { char tmp[1024]; - snprintf(tmp, sizeof(tmp), "Engine \"%s\" was not found", *engine_id); + snprintf(tmp, sizeof(tmp), STR_ENGINE_NOT_FOUND, *engine_id); return env->ThrowError(tmp); } else { return ThrowCryptoError(env, err); diff --git a/src/node_dtrace.cc b/src/node_dtrace.cc index 2572bbee585b80..1a87167538584a 100644 --- a/src/node_dtrace.cc +++ b/src/node_dtrace.cc @@ -42,76 +42,72 @@ using v8::Object; using v8::String; using v8::Value; -#define SLURP_STRING(obj, member, valp) \ - if (!(obj)->IsObject()) { \ - return env->ThrowError( \ - "expected object for " #obj " to contain string member " #member); \ - } \ - node::Utf8Value _##member(env->isolate(), \ - obj->Get(OneByteString(env->isolate(), #member))); \ - if ((*(const char **)valp = *_##member) == nullptr) \ +#define SLURP_STRING(obj, member, valp) \ + if (!(obj)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_OBJECT_TO_CONTAIN_TYPED_MEMBER, \ + #obj, "string", #member); \ + } \ + node::Utf8Value _##member(env->isolate(), \ + obj->Get(OneByteString(env->isolate(), #member))); \ + if ((*(const char **)valp = *_##member) == nullptr) \ *(const char **)valp = ""; -#define SLURP_INT(obj, member, valp) \ - if (!(obj)->IsObject()) { \ - return env->ThrowError( \ - "expected object for " #obj " to contain integer member " #member); \ - } \ - *valp = obj->Get(OneByteString(env->isolate(), #member)) \ +#define SLURP_INT(obj, member, valp) \ + if (!(obj)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_OBJECT_TO_CONTAIN_TYPED_MEMBER, \ + #obj, "integer", #member); \ + } \ + *valp = obj->Get(OneByteString(env->isolate(), #member)) \ ->ToInteger(env->isolate())->Value(); -#define SLURP_OBJECT(obj, member, valp) \ - if (!(obj)->IsObject()) { \ - return env->ThrowError( \ - "expected object for " #obj " to contain object member " #member); \ - } \ +#define SLURP_OBJECT(obj, member, valp) \ + if (!(obj)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_OBJECT_TO_CONTAIN_TYPED_MEMBER, \ + #obj, "object", #member); \ + } \ *valp = Local::Cast(obj->Get(OneByteString(env->isolate(), #member))); -#define SLURP_CONNECTION(arg, conn) \ - if (!(arg)->IsObject()) { \ - return env->ThrowError( \ - "expected argument " #arg " to be a connection object"); \ - } \ - node_dtrace_connection_t conn; \ - Local _##conn = Local::Cast(arg); \ - Local _handle = \ - (_##conn)->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "_handle")); \ - if (_handle->IsObject()) { \ - SLURP_INT(_handle.As(), fd, &conn.fd); \ - } else { \ - conn.fd = -1; \ - } \ - SLURP_STRING(_##conn, remoteAddress, &conn.remote); \ - SLURP_INT(_##conn, remotePort, &conn.port); \ +#define SLURP_CONNECTION(arg, conn) \ + if (!(arg)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_CONNECTION_OBJECT, #arg); \ + } \ + node_dtrace_connection_t conn; \ + Local _##conn = Local::Cast(arg); \ + Local _handle = \ + (_##conn)->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "_handle")); \ + if (_handle->IsObject()) { \ + SLURP_INT(_handle.As(), fd, &conn.fd); \ + } else { \ + conn.fd = -1; \ + } \ + SLURP_STRING(_##conn, remoteAddress, &conn.remote); \ + SLURP_INT(_##conn, remotePort, &conn.port); \ SLURP_INT(_##conn, bufferSize, &conn.buffered); -#define SLURP_CONNECTION_HTTP_CLIENT(arg, conn) \ - if (!(arg)->IsObject()) { \ - return env->ThrowError( \ - "expected argument " #arg " to be a connection object"); \ - } \ - node_dtrace_connection_t conn; \ - Local _##conn = Local::Cast(arg); \ - SLURP_INT(_##conn, fd, &conn.fd); \ - SLURP_STRING(_##conn, host, &conn.remote); \ - SLURP_INT(_##conn, port, &conn.port); \ +#define SLURP_CONNECTION_HTTP_CLIENT(arg, conn) \ + if (!(arg)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_CONNECTION_OBJECT, #arg); \ + } \ + node_dtrace_connection_t conn; \ + Local _##conn = Local::Cast(arg); \ + SLURP_INT(_##conn, fd, &conn.fd); \ + SLURP_STRING(_##conn, host, &conn.remote); \ + SLURP_INT(_##conn, port, &conn.port); \ SLURP_INT(_##conn, bufferSize, &conn.buffered); -#define SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(arg0, arg1, conn) \ - if (!(arg0)->IsObject()) { \ - return env->ThrowError( \ - "expected argument " #arg0 " to be a connection object"); \ - } \ - if (!(arg1)->IsObject()) { \ - return env->ThrowError( \ - "expected argument " #arg1 " to be a connection object"); \ - } \ - node_dtrace_connection_t conn; \ - Local _##conn = Local::Cast(arg0); \ - SLURP_INT(_##conn, fd, &conn.fd); \ - SLURP_INT(_##conn, bufferSize, &conn.buffered); \ - _##conn = Local::Cast(arg1); \ - SLURP_STRING(_##conn, host, &conn.remote); \ +#define SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(arg0, arg1, conn) \ + if (!(arg0)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_CONNECTION_OBJECT, #arg0); \ + } \ + if (!(arg1)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_CONNECTION_OBJECT, #arg1); \ + } \ + node_dtrace_connection_t conn; \ + Local _##conn = Local::Cast(arg0); \ + SLURP_INT(_##conn, fd, &conn.fd); \ + SLURP_INT(_##conn, bufferSize, &conn.buffered); \ + _##conn = Local::Cast(arg1); \ + SLURP_STRING(_##conn, host, &conn.remote); \ SLURP_INT(_##conn, port, &conn.port); @@ -150,8 +146,8 @@ void DTRACE_HTTP_SERVER_REQUEST(const FunctionCallbackInfo& args) { SLURP_OBJECT(arg0, headers, &headers); if (!(headers)->IsObject()) { - return env->ThrowError( - "expected object for request to contain string member headers"); + return THROWI18NERROR(env, + EXPECTED_OBJECT_FOR_REQUEST_TO_CONTAIN_STRING_HEADERS); } Local strfwdfor = headers->Get(env->x_forwarded_string()); diff --git a/src/node_file.cc b/src/node_file.cc index 57e5168ab2c2b9..b3e363f46401ec 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -44,8 +44,6 @@ using v8::Value; # define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif -#define TYPE_ERROR(msg) env->ThrowTypeError(msg) - #define GET_OFFSET(a) ((a)->IsNumber() ? (a)->IntegerValue() : -1) class FSReqWrap: public ReqWrap { @@ -318,11 +316,11 @@ static void Access(const FunctionCallbackInfo& args) { HandleScope scope(env->isolate()); if (args.Length() < 2) - return TYPE_ERROR("path and mode are required"); + return THROWI18NTYPEERROR(env, PATH_MODE_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); if (!args[1]->IsInt32()) - return TYPE_ERROR("mode must be an integer"); + return THROWI18NTYPEERROR(env, MODE_INTEGER); node::Utf8Value path(env->isolate(), args[0]); int mode = static_cast(args[1]->Int32Value()); @@ -339,9 +337,9 @@ static void Close(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return TYPE_ERROR("fd is required"); + return THROWI18NTYPEERROR(env, FD_REQUIRED); if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be a file descriptor"); + return THROWI18NTYPEERROR(env, FD_FILE_DESCRIPTOR); int fd = args[0]->Int32Value(); @@ -535,9 +533,9 @@ static void Stat(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return TYPE_ERROR("path required"); + return THROWI18NTYPEERROR(env, PATH_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); node::Utf8Value path(env->isolate(), args[0]); @@ -554,9 +552,9 @@ static void LStat(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return TYPE_ERROR("path required"); + return THROWI18NTYPEERROR(env, PATH_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); node::Utf8Value path(env->isolate(), args[0]); @@ -573,9 +571,9 @@ static void FStat(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return TYPE_ERROR("fd is required"); + return THROWI18NTYPEERROR(env, FD_REQUIRED); if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be a file descriptor"); + return THROWI18NTYPEERROR(env, FD_FILE_DESCRIPTOR); int fd = args[0]->Int32Value(); @@ -593,13 +591,13 @@ static void Symlink(const FunctionCallbackInfo& args) { int len = args.Length(); if (len < 1) - return TYPE_ERROR("target path required"); + return THROWI18NTYPEERROR(env, TARGET_PATH_REQUIRED); if (len < 2) - return TYPE_ERROR("src path required"); + return THROWI18NTYPEERROR(env, SRC_PATH_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("target path must be a string"); + return THROWI18NTYPEERROR(env, TARGET_PATH_STRING); if (!args[1]->IsString()) - return TYPE_ERROR("src path must be a string"); + return THROWI18NTYPEERROR(env, SRC_PATH_STRING); node::Utf8Value target(env->isolate(), args[0]); node::Utf8Value path(env->isolate(), args[1]); @@ -612,7 +610,7 @@ static void Symlink(const FunctionCallbackInfo& args) { } else if (strcmp(*mode, "junction") == 0) { flags |= UV_FS_SYMLINK_JUNCTION; } else if (strcmp(*mode, "file") != 0) { - return env->ThrowError("Unknown symlink type"); + return THROWI18NERROR(env, UNKNOWN_SYMLINK_TYPE); } } @@ -628,13 +626,13 @@ static void Link(const FunctionCallbackInfo& args) { int len = args.Length(); if (len < 1) - return TYPE_ERROR("src path required"); + return THROWI18NTYPEERROR(env, SRC_PATH_REQUIRED); if (len < 2) - return TYPE_ERROR("dest path required"); + return THROWI18NTYPEERROR(env, DEST_PATH_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("src path must be a string"); + return THROWI18NTYPEERROR(env, SRC_PATH_STRING); if (!args[1]->IsString()) - return TYPE_ERROR("dest path must be a string"); + return THROWI18NTYPEERROR(env, DEST_PATH_STRING); node::Utf8Value orig_path(env->isolate(), args[0]); node::Utf8Value new_path(env->isolate(), args[1]); @@ -650,9 +648,9 @@ static void ReadLink(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return TYPE_ERROR("path required"); + return THROWI18NTYPEERROR(env, PATH_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); node::Utf8Value path(env->isolate(), args[0]); @@ -671,13 +669,13 @@ static void Rename(const FunctionCallbackInfo& args) { int len = args.Length(); if (len < 1) - return TYPE_ERROR("old path required"); + return THROWI18NTYPEERROR(env, OLD_PATH_REQUIRED); if (len < 2) - return TYPE_ERROR("new path required"); + return THROWI18NTYPEERROR(env, NEW_PATH_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("old path must be a string"); + return THROWI18NTYPEERROR(env, OLD_PATH_STRING); if (!args[1]->IsString()) - return TYPE_ERROR("new path must be a string"); + return THROWI18NTYPEERROR(env, NEW_PATH_STRING); node::Utf8Value old_path(env->isolate(), args[0]); node::Utf8Value new_path(env->isolate(), args[1]); @@ -693,9 +691,9 @@ static void FTruncate(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 2) - return TYPE_ERROR("fd and length are required"); + return THROWI18NTYPEERROR(env, FD_LENGTH_REQUIRED); if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be a file descriptor"); + return THROWI18NTYPEERROR(env, FD_FILE_DESCRIPTOR); int fd = args[0]->Int32Value(); @@ -706,7 +704,7 @@ static void FTruncate(const FunctionCallbackInfo& args) { if (!len_v->IsUndefined() && !len_v->IsNull() && !IsInt64(len_v->NumberValue())) { - return env->ThrowTypeError("Not an integer"); + return THROWI18NTYPEERROR(env, NOT_AN_INTEGER); } const int64_t len = len_v->IntegerValue(); @@ -722,9 +720,9 @@ static void Fdatasync(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return TYPE_ERROR("fd is required"); + return THROWI18NTYPEERROR(env, FD_REQUIRED); if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be a file descriptor"); + return THROWI18NTYPEERROR(env, FD_FILE_DESCRIPTOR); int fd = args[0]->Int32Value(); @@ -739,9 +737,9 @@ static void Fsync(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return TYPE_ERROR("fd is required"); + return THROWI18NTYPEERROR(env, FD_REQUIRED); if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be a file descriptor"); + return THROWI18NTYPEERROR(env, FD_FILE_DESCRIPTOR); int fd = args[0]->Int32Value(); @@ -756,9 +754,9 @@ static void Unlink(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return TYPE_ERROR("path required"); + return THROWI18NTYPEERROR(env, PATH_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); node::Utf8Value path(env->isolate(), args[0]); @@ -773,9 +771,9 @@ static void RMDir(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return TYPE_ERROR("path required"); + return THROWI18NTYPEERROR(env, PATH_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); node::Utf8Value path(env->isolate(), args[0]); @@ -790,11 +788,11 @@ static void MKDir(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 2) - return TYPE_ERROR("path and mode are required"); + return THROWI18NTYPEERROR(env, PATH_MODE_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); if (!args[1]->IsInt32()) - return TYPE_ERROR("mode must be an integer"); + return THROWI18NTYPEERROR(env, MODE_INTEGER); node::Utf8Value path(env->isolate(), args[0]); int mode = static_cast(args[1]->Int32Value()); @@ -810,9 +808,9 @@ static void ReadDir(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return TYPE_ERROR("path required"); + return THROWI18NTYPEERROR(env, PATH_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); node::Utf8Value path(env->isolate(), args[0]); @@ -860,17 +858,17 @@ static void Open(const FunctionCallbackInfo& args) { int len = args.Length(); if (len < 1) - return TYPE_ERROR("path required"); + return THROWI18NTYPEERROR(env, PATH_REQUIRED); if (len < 2) - return TYPE_ERROR("flags required"); + return THROWI18NTYPEERROR(env, FLAGS_REQUIRED); if (len < 3) - return TYPE_ERROR("mode required"); + return THROWI18NTYPEERROR(env, MODE_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); if (!args[1]->IsInt32()) - return TYPE_ERROR("flags must be an int"); + return THROWI18NTYPEERROR(env, FLAGS_INT); if (!args[2]->IsInt32()) - return TYPE_ERROR("mode must be an int"); + return THROWI18NTYPEERROR(env, MODE_INTEGER); node::Utf8Value path(env->isolate(), args[0]); int flags = args[1]->Int32Value(); @@ -898,7 +896,7 @@ static void WriteBuffer(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsInt32()) - return env->ThrowTypeError("First argument must be file descriptor"); + return THROWI18NTYPEERROR(env, FIRST_ARGUMENT_FILEDESCRIPTOR); CHECK(Buffer::HasInstance(args[1])); @@ -912,13 +910,13 @@ static void WriteBuffer(const FunctionCallbackInfo& args) { Local req = args[5]; if (off > buffer_length) - return env->ThrowRangeError("offset out of bounds"); + return THROWI18NRANGEERROR(env, OFFSET_OUTOFBOUNDS); if (len > buffer_length) - return env->ThrowRangeError("length out of bounds"); + return THROWI18NRANGEERROR(env, LENGTH_OUTOFBOUNDS); if (off + len < off) - return env->ThrowRangeError("off + len overflow"); + return THROWI18NRANGEERROR(env, OFF_LEN_OVERFLOW); if (!Buffer::IsWithinBounds(off, len, buffer_length)) - return env->ThrowRangeError("off + len > buffer.length"); + return THROWI18NRANGEERROR(env, OFF_LEN_BUFLEN); buf += off; @@ -968,7 +966,7 @@ static void WriteBuffers(const FunctionCallbackInfo& args) { if (!Buffer::HasInstance(chunk)) { if (iovs != s_iovs) delete[] iovs; - return env->ThrowTypeError("Array elements all need to be buffers"); + return THROWI18NERROR(env, ARRAY_ELEMENT_BUFFERS); } iovs[i] = uv_buf_init(Buffer::Data(chunk), Buffer::Length(chunk)); @@ -1000,7 +998,7 @@ static void WriteString(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsInt32()) - return env->ThrowTypeError("First argument must be file descriptor"); + return THROWI18NTYPEERROR(env, FIRST_ARGUMENT_FILEDESCRIPTOR); Local req; Local string = args[1]; @@ -1078,11 +1076,11 @@ static void Read(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 2) - return TYPE_ERROR("fd and buffer are required"); + return THROWI18NTYPEERROR(env, FD_BUFFER_REQUIRED); if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be a file descriptor"); + return THROWI18NTYPEERROR(env, FD_FILE_DESCRIPTOR); if (!Buffer::HasInstance(args[1])) - return TYPE_ERROR("Second argument needs to be a buffer"); + return THROWI18NTYPEERROR(env, SECOND_ARGUMENT_BUFFER); int fd = args[0]->Int32Value(); @@ -1099,12 +1097,12 @@ static void Read(const FunctionCallbackInfo& args) { size_t off = args[2]->Int32Value(); if (off >= buffer_length) { - return env->ThrowError("Offset is out of bounds"); + return THROWI18NERROR(env, OFFSET_OUTOFBOUNDS); } len = args[3]->Int32Value(); if (!Buffer::IsWithinBounds(off, len, buffer_length)) - return env->ThrowRangeError("Length extends beyond buffer"); + return THROWI18NRANGEERROR(env, LENGTH_BEYOND_BUFFER); pos = GET_OFFSET(args[4]); @@ -1130,11 +1128,11 @@ static void Chmod(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 2) - return TYPE_ERROR("path and mode are required"); + return THROWI18NTYPEERROR(env, PATH_MODE_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); if (!args[1]->IsInt32()) - return TYPE_ERROR("mode must be an integer"); + return THROWI18NTYPEERROR(env, MODE_INTEGER); node::Utf8Value path(env->isolate(), args[0]); int mode = static_cast(args[1]->Int32Value()); @@ -1154,11 +1152,11 @@ static void FChmod(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 2) - return TYPE_ERROR("fd and mode are required"); + return THROWI18NTYPEERROR(env, FD_MODE_REQUIRED); if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be a file descriptor"); + return THROWI18NTYPEERROR(env, FD_FILE_DESCRIPTOR); if (!args[1]->IsInt32()) - return TYPE_ERROR("mode must be an integer"); + return THROWI18NTYPEERROR(env, MODE_INTEGER); int fd = args[0]->Int32Value(); int mode = static_cast(args[1]->Int32Value()); @@ -1179,17 +1177,17 @@ static void Chown(const FunctionCallbackInfo& args) { int len = args.Length(); if (len < 1) - return TYPE_ERROR("path required"); + return THROWI18NTYPEERROR(env, PATH_REQUIRED); if (len < 2) - return TYPE_ERROR("uid required"); + return THROWI18NTYPEERROR(env, UID_REQUIRED); if (len < 3) - return TYPE_ERROR("gid required"); + return THROWI18NTYPEERROR(env, GID_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); if (!args[1]->IsUint32()) - return TYPE_ERROR("uid must be an unsigned int"); + return THROWI18NTYPEERROR(env, UID_UINT); if (!args[2]->IsUint32()) - return TYPE_ERROR("gid must be an unsigned int"); + return THROWI18NTYPEERROR(env, GID_UINT); node::Utf8Value path(env->isolate(), args[0]); uv_uid_t uid = static_cast(args[1]->Uint32Value()); @@ -1211,17 +1209,17 @@ static void FChown(const FunctionCallbackInfo& args) { int len = args.Length(); if (len < 1) - return TYPE_ERROR("fd required"); + return THROWI18NTYPEERROR(env, FD_REQUIRED); if (len < 2) - return TYPE_ERROR("uid required"); + return THROWI18NTYPEERROR(env, UID_REQUIRED); if (len < 3) - return TYPE_ERROR("gid required"); + return THROWI18NTYPEERROR(env, GID_REQUIRED); if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be an int"); + return THROWI18NTYPEERROR(env, FD_INTEGER); if (!args[1]->IsUint32()) - return TYPE_ERROR("uid must be an unsigned int"); + return THROWI18NTYPEERROR(env, UID_UINT); if (!args[2]->IsUint32()) - return TYPE_ERROR("gid must be an unsigned int"); + return THROWI18NTYPEERROR(env, GID_UINT); int fd = args[0]->Int32Value(); uv_uid_t uid = static_cast(args[1]->Uint32Value()); @@ -1240,17 +1238,17 @@ static void UTimes(const FunctionCallbackInfo& args) { int len = args.Length(); if (len < 1) - return TYPE_ERROR("path required"); + return THROWI18NTYPEERROR(env, PATH_REQUIRED); if (len < 2) - return TYPE_ERROR("atime required"); + return THROWI18NTYPEERROR(env, ATIME_REQUIRED); if (len < 3) - return TYPE_ERROR("mtime required"); + return THROWI18NTYPEERROR(env, MTIME_REQUIRED); if (!args[0]->IsString()) - return TYPE_ERROR("path must be a string"); + return THROWI18NTYPEERROR(env, PATH_STRING); if (!args[1]->IsNumber()) - return TYPE_ERROR("atime must be a number"); + return THROWI18NTYPEERROR(env, ATIME_NUMBER); if (!args[2]->IsNumber()) - return TYPE_ERROR("mtime must be a number"); + return THROWI18NTYPEERROR(env, MTIME_NUMBER); const node::Utf8Value path(env->isolate(), args[0]); const double atime = static_cast(args[1]->NumberValue()); @@ -1268,17 +1266,17 @@ static void FUTimes(const FunctionCallbackInfo& args) { int len = args.Length(); if (len < 1) - return TYPE_ERROR("fd required"); + return THROWI18NTYPEERROR(env, FD_REQUIRED); if (len < 2) - return TYPE_ERROR("atime required"); + return THROWI18NTYPEERROR(env, ATIME_REQUIRED); if (len < 3) - return TYPE_ERROR("mtime required"); + return THROWI18NTYPEERROR(env, MTIME_REQUIRED); if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be an int"); + return THROWI18NTYPEERROR(env, FD_INTEGER); if (!args[1]->IsNumber()) - return TYPE_ERROR("atime must be a number"); + return THROWI18NTYPEERROR(env, ATIME_NUMBER); if (!args[2]->IsNumber()) - return TYPE_ERROR("mtime must be a number"); + return THROWI18NTYPEERROR(env, MTIME_NUMBER); const int fd = args[0]->Int32Value(); const double atime = static_cast(args[1]->NumberValue()); diff --git a/src/node_lttng.cc b/src/node_lttng.cc index b70f6ca80983e8..53ecb536625a46 100644 --- a/src/node_lttng.cc +++ b/src/node_lttng.cc @@ -37,76 +37,72 @@ using v8::Object; using v8::String; using v8::Value; -#define SLURP_STRING(obj, member, valp) \ - if (!(obj)->IsObject()) { \ - return env->ThrowError( \ - "expected object for " #obj " to contain string member " #member); \ - } \ - node::Utf8Value _##member(env->isolate(), \ - obj->Get(OneByteString(env->isolate(), #member))); \ - if ((*(const char **)valp = *_##member) == nullptr) \ +#define SLURP_STRING(obj, member, valp) \ + if (!(obj)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_OBJECT_TO_CONTAIN_TYPED_MEMBER, \ + #obj, "string", #member); \ + } \ + node::Utf8Value _##member(env->isolate(), \ + obj->Get(OneByteString(env->isolate(), #member))); \ + if ((*(const char **)valp = *_##member) == nullptr) \ *(const char **)valp = ""; -#define SLURP_INT(obj, member, valp) \ - if (!(obj)->IsObject()) { \ - return env->ThrowError( \ - "expected object for " #obj " to contain integer member " #member); \ - } \ - *valp = obj->Get(OneByteString(env->isolate(), #member)) \ +#define SLURP_INT(obj, member, valp) \ + if (!(obj)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_OBJECT_TO_CONTAIN_TYPED_MEMBER, \ + #obj, "integer", #member); \ + } \ + *valp = obj->Get(OneByteString(env->isolate(), #member)) \ ->ToInteger(env->isolate())->Value(); -#define SLURP_OBJECT(obj, member, valp) \ - if (!(obj)->IsObject()) { \ - return env->ThrowError( \ - "expected object for " #obj " to contain object member " #member); \ - } \ +#define SLURP_OBJECT(obj, member, valp) \ + if (!(obj)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_OBJECT_TO_CONTAIN_TYPED_MEMBER, \ + #obj, "object", #member); \ + } \ *valp = Local::Cast(obj->Get(OneByteString(env->isolate(), #member))); -#define SLURP_CONNECTION(arg, conn) \ - if (!(arg)->IsObject()) { \ - return env->ThrowError( \ - "expected argument " #arg " to be a connection object"); \ - } \ - node_lttng_connection_t conn; \ - Local _##conn = Local::Cast(arg); \ - Local _handle = \ - (_##conn)->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "_handle")); \ - if (_handle->IsObject()) { \ - SLURP_INT(_handle.As(), fd, &conn.fd); \ - } else { \ - conn.fd = -1; \ - } \ - SLURP_STRING(_##conn, remoteAddress, &conn.remote); \ - SLURP_INT(_##conn, remotePort, &conn.port); \ +#define SLURP_CONNECTION(arg, conn) \ + if (!(arg)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_CONNECTION_OBJECT, #arg); \ + } \ + node_lttng_connection_t conn; \ + Local _##conn = Local::Cast(arg); \ + Local _handle = \ + (_##conn)->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "_handle")); \ + if (_handle->IsObject()) { \ + SLURP_INT(_handle.As(), fd, &conn.fd); \ + } else { \ + conn.fd = -1; \ + } \ + SLURP_STRING(_##conn, remoteAddress, &conn.remote); \ + SLURP_INT(_##conn, remotePort, &conn.port); \ SLURP_INT(_##conn, bufferSize, &conn.buffered); -#define SLURP_CONNECTION_HTTP_CLIENT(arg, conn) \ - if (!(arg)->IsObject()) { \ - return env->ThrowError( \ - "expected argument " #arg " to be a connection object"); \ - } \ - node_lttng_connection_t conn; \ - Local _##conn = Local::Cast(arg); \ - SLURP_INT(_##conn, fd, &conn.fd); \ - SLURP_STRING(_##conn, host, &conn.remote); \ - SLURP_INT(_##conn, port, &conn.port); \ +#define SLURP_CONNECTION_HTTP_CLIENT(arg, conn) \ + if (!(arg)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_CONNECTION_OBJECT, #arg); \ + } \ + node_lttng_connection_t conn; \ + Local _##conn = Local::Cast(arg); \ + SLURP_INT(_##conn, fd, &conn.fd); \ + SLURP_STRING(_##conn, host, &conn.remote); \ + SLURP_INT(_##conn, port, &conn.port); \ SLURP_INT(_##conn, bufferSize, &conn.buffered); -#define SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(arg0, arg1, conn) \ - if (!(arg0)->IsObject()) { \ - return env->ThrowError( \ - "expected argument " #arg0 " to be a connection object"); \ - } \ - if (!(arg1)->IsObject()) { \ - return env->ThrowError( \ - "expected argument " #arg1 " to be a connection object"); \ - } \ - node_lttng_connection_t conn; \ - Local _##conn = Local::Cast(arg0); \ - SLURP_INT(_##conn, fd, &conn.fd); \ - SLURP_INT(_##conn, bufferSize, &conn.buffered); \ - _##conn = Local::Cast(arg1); \ - SLURP_STRING(_##conn, host, &conn.remote); \ +#define SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(arg0, arg1, conn) \ + if (!(arg0)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_CONNECTION_OBJECT, #arg0); \ + } \ + if (!(arg1)->IsObject()) { \ + return VTHROWI18NERROR(env, EXPECTED_CONNECTION_OBJECT, #arg1); \ + } \ + node_lttng_connection_t conn; \ + Local _##conn = Local::Cast(arg0); \ + SLURP_INT(_##conn, fd, &conn.fd); \ + SLURP_INT(_##conn, bufferSize, &conn.buffered); \ + _##conn = Local::Cast(arg1); \ + SLURP_STRING(_##conn, host, &conn.remote); \ SLURP_INT(_##conn, port, &conn.port); @@ -148,8 +144,8 @@ void LTTNG_HTTP_SERVER_REQUEST(const FunctionCallbackInfo& args) { SLURP_OBJECT(arg0, headers, &headers); if (!(headers)->IsObject()) { - return env->ThrowError( - "expected object for request to contain string member headers"); + return THROWI18NERROR(env, + EXPECTED_OBJECT_FOR_REQUEST_TO_CONTAIN_STRING_HEADERS); } Local strfwdfor = headers->Get(env->x_forwarded_string()); diff --git a/src/node_main.cc b/src/node_main.cc index 58e747e52c49ef..07f4297926b725 100644 --- a/src/node_main.cc +++ b/src/node_main.cc @@ -16,7 +16,7 @@ int wmain(int argc, wchar_t *wargv[]) { nullptr); if (size == 0) { // This should never happen. - fprintf(stderr, "Could not convert arguments to utf8."); + fprintf(stderr, STR_CONVERT_ARGS_TO_UTF8_FAIL); exit(1); } // Do the actual conversion @@ -31,7 +31,7 @@ int wmain(int argc, wchar_t *wargv[]) { nullptr); if (result == 0) { // This should never happen. - fprintf(stderr, "Could not convert arguments to utf8."); + fprintf(stderr, STR_CONVERT_ARGS_TO_UTF8_FAIL); exit(1); } } diff --git a/src/node_messages.cc b/src/node_messages.cc new file mode 100644 index 00000000000000..90ab6771957f40 --- /dev/null +++ b/src/node_messages.cc @@ -0,0 +1,55 @@ + +#include "node_messages.h" +#include "node.h" +#include "v8.h" +#include "util.h" +#include "env.h" +#include "env-inl.h" + +namespace node { + +using v8::Isolate; +using v8::Local; +using v8::Array; +using v8::Object; +using v8::String; +using v8::Number; +using v8::Value; +using v8::FunctionCallbackInfo; +using v8::PropertyAttribute; +using v8::ReadOnly; +using v8::DontDelete; + +#define DEFINE_MSG_CONSTANT(target, constant) \ + do { \ + Isolate* isolate = target->GetIsolate(); \ + Local constant_name = OneByteString(isolate, #constant); \ + Local constant_value = \ + Number::New(isolate, static_cast(MSG_ ## constant)); \ + PropertyAttribute constant_attributes = \ + static_cast(ReadOnly | DontDelete); \ + (target)->ForceSet(constant_name, constant_value, constant_attributes); \ + } \ + while (0) + +void DefineMessages(Environment* env, Local target) { + // Set the Message ID Constants + Isolate* isolate = target->GetIsolate(); + Local keys = Array::New(isolate, MSG_UNKNOWN); + Local messages = Array::New(isolate, MSG_UNKNOWN); + +#define NODE_MSG_CONSTANT(id, msg) \ + DEFINE_MSG_CONSTANT(target, id); \ + keys->Set(MSG_ ## id, OneByteString(isolate, #id)); \ + messages->Set(MSG_ ## id, String::NewFromUtf8(isolate, msg)); + NODE_MESSAGES(NODE_MSG_CONSTANT); +#undef NODE_MSG_CONSTANT + + PropertyAttribute constant_attributes = + static_cast(ReadOnly | DontDelete); + (target)->ForceSet(OneByteString(isolate, "keys"), + keys, constant_attributes); + (target)->ForceSet(OneByteString(isolate, "messages"), + messages, constant_attributes); +} +} // namespace node diff --git a/src/node_messages.h b/src/node_messages.h new file mode 100644 index 00000000000000..cd37cd5fa73fc2 --- /dev/null +++ b/src/node_messages.h @@ -0,0 +1,14 @@ +#ifndef SRC_NODE_MESSAGES_H_ +#define SRC_NODE_MESSAGES_H_ + +#include "node.h" +#include "env.h" +#include "v8.h" + +namespace node { + +void DefineMessages(Environment* env, v8::Local target); + +} // namespace node + +#endif // SRC_NODE_MESSAGES_H_ diff --git a/src/node_util.cc b/src/node_util.cc index 8475468c1f4afe..5733f17437de2c 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -41,10 +41,10 @@ static void GetHiddenValue(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsObject()) - return env->ThrowTypeError("obj must be an object"); + return THROWI18NTYPEERROR(env, OBJ_OBJECT); if (!args[1]->IsString()) - return env->ThrowTypeError("name must be a string"); + return THROWI18NTYPEERROR(env, NAME_STRING); Local obj = args[0].As(); Local name = args[1].As(); @@ -56,10 +56,10 @@ static void SetHiddenValue(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsObject()) - return env->ThrowTypeError("obj must be an object"); + return THROWI18NTYPEERROR(env, OBJ_OBJECT); if (!args[1]->IsString()) - return env->ThrowTypeError("name must be a string"); + return THROWI18NTYPEERROR(env, NAME_STRING); Local obj = args[0].As(); Local name = args[1].As(); diff --git a/src/node_v8.cc b/src/node_v8.cc index 9f456daec464ce..c7eac33a59d7fd 100644 --- a/src/node_v8.cc +++ b/src/node_v8.cc @@ -49,9 +49,9 @@ void SetFlagsFromString(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1) - return env->ThrowTypeError("v8 flag is required"); + return THROWI18NTYPEERROR(env, V8_FLAG_REQUIRED); if (!args[0]->IsString()) - return env->ThrowTypeError("v8 flag must be a string"); + return THROWI18NTYPEERROR(env, V8_FLAG_STRING); String::Utf8Value flags(args[0]); V8::SetFlagsFromString(*flags, flags.length()); diff --git a/src/node_zlib.cc b/src/node_zlib.cc index f7e808cf1b1d82..b47231abbfb3b4 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -273,7 +273,7 @@ class ZCtx : public AsyncWrap { case Z_OK: case Z_BUF_ERROR: if (ctx->strm_.avail_out != 0 && ctx->flush_ == Z_FINISH) { - ZCtx::Error(ctx, "unexpected end of file"); + ZCtx::Error(ctx, STR_UNEXPECTED_EOF); return false; } case Z_STREAM_END: @@ -281,13 +281,13 @@ class ZCtx : public AsyncWrap { break; case Z_NEED_DICT: if (ctx->dictionary_ == nullptr) - ZCtx::Error(ctx, "Missing dictionary"); + ZCtx::Error(ctx, STR_MISSING_DICTIONARY); else - ZCtx::Error(ctx, "Bad dictionary"); + ZCtx::Error(ctx, STR_BAD_DICTIONARY); return false; default: // something else. - ZCtx::Error(ctx, "Zlib error"); + ZCtx::Error(ctx, STR_ZLIB_ERROR); return false; } @@ -353,12 +353,12 @@ class ZCtx : public AsyncWrap { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1 || !args[0]->IsInt32()) { - return env->ThrowTypeError("Bad argument"); + return THROWI18NTYPEERROR(env, BAD_ARGUMENT); } node_zlib_mode mode = static_cast(args[0]->Int32Value()); if (mode < DEFLATE || mode > UNZIP) { - return env->ThrowTypeError("Bad argument"); + return THROWI18NTYPEERROR(env, BAD_ARGUMENT); } new ZCtx(env, args.This(), mode); @@ -468,7 +468,7 @@ class ZCtx : public AsyncWrap { } if (ctx->err_ != Z_OK) { - ZCtx::Error(ctx, "Init error"); + ZCtx::Error(ctx, STR_INIT_ERROR); } @@ -497,7 +497,7 @@ class ZCtx : public AsyncWrap { } if (ctx->err_ != Z_OK) { - ZCtx::Error(ctx, "Failed to set dictionary"); + ZCtx::Error(ctx, STR_FAILED_TO_SET_DICTIONARY); } } @@ -514,7 +514,7 @@ class ZCtx : public AsyncWrap { } if (ctx->err_ != Z_OK && ctx->err_ != Z_BUF_ERROR) { - ZCtx::Error(ctx, "Failed to set parameters"); + ZCtx::Error(ctx, STR_FAILED_TO_SET_PARAMETERS); } } @@ -535,7 +535,7 @@ class ZCtx : public AsyncWrap { } if (ctx->err_ != Z_OK) { - ZCtx::Error(ctx, "Failed to reset stream"); + ZCtx::Error(ctx, STR_FAILED_TO_RESET_STREAM); } } diff --git a/src/process_wrap.cc b/src/process_wrap.cc index adf1606591f156..8696729b8c17b4 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -122,12 +122,12 @@ class ProcessWrap : public HandleWrap { if (uid_v->IsInt32()) { int32_t uid = uid_v->Int32Value(); if (uid & ~((uv_uid_t) ~0)) { - return env->ThrowRangeError("options.uid is out of range"); + return THROWI18NRANGEERROR(env, UID_OUTOFRANGE); } options.flags |= UV_PROCESS_SETUID; options.uid = (uv_uid_t) uid; } else if (!uid_v->IsUndefined() && !uid_v->IsNull()) { - return env->ThrowTypeError("options.uid should be a number"); + return THROWI18NTYPEERROR(env, OPTIONS_UID_NUMBER); } // options.gid @@ -135,12 +135,12 @@ class ProcessWrap : public HandleWrap { if (gid_v->IsInt32()) { int32_t gid = gid_v->Int32Value(); if (gid & ~((uv_gid_t) ~0)) { - return env->ThrowRangeError("options.gid is out of range"); + return THROWI18NRANGEERROR(env, GID_OUTOFRANGE); } options.flags |= UV_PROCESS_SETGID; options.gid = (uv_gid_t) gid; } else if (!gid_v->IsUndefined() && !gid_v->IsNull()) { - return env->ThrowTypeError("options.gid should be a number"); + return THROWI18NTYPEERROR(env, OPTIONS_GID_NUMBER); } // TODO(bnoordhuis) is this possible to do without mallocing ? @@ -152,7 +152,7 @@ class ProcessWrap : public HandleWrap { if (file.length() > 0) { options.file = *file; } else { - return env->ThrowTypeError("Bad argument"); + return THROWI18NTYPEERROR(env, BAD_ARGUMENT); } // options.args diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index e6236a6e529864..ea65773d47d789 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -160,7 +160,7 @@ void StreamWrap::OnAllocImpl(size_t size, uv_buf_t* buf, void* ctx) { if (buf->base == nullptr && size > 0) { FatalError( "node::StreamWrap::DoAlloc(size_t, uv_buf_t*, void*)", - "Out Of Memory"); + STR_OUTOFMEMORY); } } diff --git a/src/string_bytes.h b/src/string_bytes.h index 79520d24705ac0..f65d13a91cb70d 100644 --- a/src/string_bytes.h +++ b/src/string_bytes.h @@ -29,7 +29,7 @@ class StringBytes { enum encoding _default) { enum encoding enc = ParseEncoding(env->isolate(), encoding, _default); if (!StringBytes::IsValidString(env->isolate(), string, enc)) { - env->ThrowTypeError("Bad input string"); + THROWI18NTYPEERROR(env, BAD_INPUT_STRING); return false; } diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index d7bf4ed8bee784..599673e99f05e4 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -164,15 +164,13 @@ void TLSWrap::Wrap(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() < 1 || !args[0]->IsObject()) { - return env->ThrowTypeError( - "First argument should be a StreamWrap instance"); + return THROWI18NTYPEERROR(env, FIRST_ARGUMENT_STREAMWRAP); } if (args.Length() < 2 || !args[1]->IsObject()) { - return env->ThrowTypeError( - "Second argument should be a SecureContext instance"); + return THROWI18NTYPEERROR(env, SECOND_ARGUMENT_SECURECONTEXT); } if (args.Length() < 3 || !args[2]->IsBoolean()) - return env->ThrowTypeError("Third argument should be boolean"); + return THROWI18NTYPEERROR(env, THIRD_AGUMENT_BOOLEAN); Local stream_obj = args[0].As(); Local sc = args[1].As(); @@ -217,7 +215,7 @@ void TLSWrap::Start(const FunctionCallbackInfo& args) { TLSWrap* wrap = Unwrap(args.Holder()); if (wrap->started_) - return env->ThrowError("Already started."); + return THROWI18NERROR(env, ALREADY_STARTED); wrap->started_ = true; // Send ClientHello handshake @@ -726,10 +724,10 @@ void TLSWrap::SetVerifyMode(const FunctionCallbackInfo& args) { TLSWrap* wrap = Unwrap(args.Holder()); if (args.Length() < 2 || !args[0]->IsBoolean() || !args[1]->IsBoolean()) - return env->ThrowTypeError("Bad arguments, expected two booleans"); + return THROWI18NTYPEERROR(env, BAD_ARGUMENTS_TWO_BOOLEANS); if (wrap->ssl_ == nullptr) - return env->ThrowTypeError("SetVerifyMode after destroySSL"); + return THROWI18NTYPEERROR(env, SETVERIFYMODE_AFTER_DESTROYSSL); int verify_mode; if (wrap->is_server()) { @@ -757,8 +755,8 @@ void TLSWrap::EnableSessionCallbacks( const FunctionCallbackInfo& args) { TLSWrap* wrap = Unwrap(args.Holder()); if (wrap->ssl_ == nullptr) { - return wrap->env()->ThrowTypeError( - "EnableSessionCallbacks after destroySSL"); + return THROWI18NTYPEERROR(wrap->env(), + ENABLESESSIONCALLBACKS_AFTER_DESTROYSSL); } wrap->enable_session_callbacks(); NodeBIO::FromBIO(wrap->enc_in_)->set_initial(kMaxHelloLength); @@ -821,10 +819,10 @@ void TLSWrap::SetServername(const FunctionCallbackInfo& args) { TLSWrap* wrap = Unwrap(args.Holder()); if (args.Length() < 1 || !args[0]->IsString()) - return env->ThrowTypeError("First argument should be a string"); + return THROWI18NTYPEERROR(env, FIRST_ARGUMENT_STRING); if (wrap->started_) - return env->ThrowError("Already started."); + return THROWI18NERROR(env, ALREADY_STARTED); if (!wrap->is_client()) return; diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index cb678f14fb3826..5f39f4f38c6a22 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -347,7 +347,7 @@ void UDPWrap::OnAlloc(uv_handle_t* handle, if (buf->base == nullptr && suggested_size > 0) { FatalError("node::UDPWrap::OnAlloc(uv_handle_t*, size_t, uv_buf_t*)", - "Out Of Memory"); + STR_OUTOFMEMORY); } } diff --git a/src/uv.cc b/src/uv.cc index d03e7750083b4c..7b33a543f27428 100644 --- a/src/uv.cc +++ b/src/uv.cc @@ -20,7 +20,7 @@ void ErrName(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); int err = args[0]->Int32Value(); if (err >= 0) - return env->ThrowError("err >= 0"); + return THROWI18NERROR(env, ERR_NOT_ZERO); const char* name = uv_err_name(err); args.GetReturnValue().Set(OneByteString(env->isolate(), name)); } diff --git a/test/message/core_line_numbers.out b/test/message/core_line_numbers.out index c4909774a0e6ec..909a7a573c93f3 100644 --- a/test/message/core_line_numbers.out +++ b/test/message/core_line_numbers.out @@ -1,9 +1,9 @@ -punycode.js:67 - throw new RangeError(errors[type]); +punycode.js:69 + throw new RangeError(I18N(errors[type])); ^ RangeError: Invalid input - at error (punycode.js:67:*) + at error (punycode.js:69:*) at Object.decode (punycode.js:*:*) at Object. (*test*message*core_line_numbers.js:*:*) at Module._compile (module.js:*:*) diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 818f4574daba04..c47e3a079c1e33 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -455,8 +455,7 @@ function testBlockTypeError(method, block) { method(block); threw = false; } catch (e) { - assert.equal(e.toString(), - 'TypeError: "block" argument must be a function'); + assert(/^TypeError: 'block' must be a function/.test(e.toString())); } assert.ok(threw); diff --git a/test/parallel/test-buffer.js b/test/parallel/test-buffer.js index 1ca159b0926422..fbd37f0612fc21 100644 --- a/test/parallel/test-buffer.js +++ b/test/parallel/test-buffer.js @@ -201,7 +201,7 @@ try { } catch (err) { caught_error = err; } -assert.strictEqual('Unknown encoding: invalid', caught_error.message); +assert(/^Unknown encoding: invalid/.test(caught_error.message)); // invalid encoding for Buffer.write caught_error = null; @@ -210,7 +210,7 @@ try { } catch (err) { caught_error = err; } -assert.strictEqual('Unknown encoding: invalid', caught_error.message); +assert(/^Unknown encoding: invalid/.test(caught_error.message)); // try to create 0-length buffers new Buffer(''); @@ -1319,13 +1319,15 @@ assert.throws(function() { Buffer(10).copy(); }); +const erregex = /^'obj' must be a number, Buffer, array or string/; + assert.throws(function() { new Buffer(); -}, /Must start with number, buffer, array or string/); +}, err => erregex.test(err.message)); assert.throws(function() { new Buffer(null); -}, /Must start with number, buffer, array or string/); +}, err => erregex.test(err.message)); // Test prototype getters don't throw diff --git a/test/parallel/test-c-ares.js b/test/parallel/test-c-ares.js index b7802881f8e47c..9b598dc659b703 100644 --- a/test/parallel/test-c-ares.js +++ b/test/parallel/test-c-ares.js @@ -1,9 +1,10 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +const common = require('../common'); +const assert = require('assert'); -var dns = require('dns'); +const dns = require('dns'); +const regex = /^Unknown type/; // Try resolution without callback @@ -23,9 +24,9 @@ dns.lookup('::1', function(error, result, addressType) { }); // Try calling resolve with an unsupported type. -assert.throws(function() { +assert.throws(() => { dns.resolve('www.google.com', 'HI'); -}, /Unknown type/); +}, err => regex.test(err.message)); // Windows doesn't usually have an entry for localhost 127.0.0.1 in // C:\Windows\System32\drivers\etc\hosts diff --git a/test/parallel/test-child-process-spawn-typeerror.js b/test/parallel/test-child-process-spawn-typeerror.js index bf59779a75ff5d..622c6bf24d2b6b 100644 --- a/test/parallel/test-child-process-spawn-typeerror.js +++ b/test/parallel/test-child-process-spawn-typeerror.js @@ -7,10 +7,16 @@ const execFile = child_process.execFile; const common = require('../common'); const cmd = common.isWindows ? 'rundll32' : 'ls'; const invalidcmd = 'hopefully_you_dont_have_this_on_your_machine'; -const invalidArgsMsg = /Incorrect value of args option/; -const invalidOptionsMsg = /"options" argument must be an object/; const empty = common.fixturesDir + '/empty.js'; +const invalidOptionsMsg = (err) => { + return /^'options' argument must be a\(n\) object/.test(err.message); +}; + +const invalidArgsMsg = (err) => { + return /^Incorrect value of args option/.test(err.message); +}; + assert.throws(function() { var child = spawn(invalidcmd, 'this is not an array'); child.on('error', common.fail); diff --git a/test/parallel/test-child-process-validate-stdio.js b/test/parallel/test-child-process-validate-stdio.js index 0a12e4f54c5306..847756ce8d6261 100644 --- a/test/parallel/test-child-process-validate-stdio.js +++ b/test/parallel/test-child-process-validate-stdio.js @@ -2,18 +2,22 @@ // Flags: --expose_internals require('../common'); -var assert = require('assert'); -var _validateStdio = require('internal/child_process')._validateStdio; +const assert = require('assert'); +const _validateStdio = require('internal/child_process')._validateStdio; + +function checkerr(err) { + return /^Incorrect value of stdio option: /.test(err.message); +} + +function checkerr2(err) { + return /^IPC cannot be used with synchronous fork/.test(err.message); +} // should throw if string and not ignore, pipe, or inherit -assert.throws(function() { - _validateStdio('foo'); -}, /Incorrect value of stdio option/); +assert.throws(() => _validateStdio('foo'), checkerr); // should throw if not a string or array -assert.throws(function() { - _validateStdio(600); -}, /Incorrect value of stdio option/); +assert.throws(() => _validateStdio(600), checkerr); // should populate stdio with undefined if len < 3 var stdio1 = []; @@ -25,9 +29,7 @@ assert.equal(result.hasOwnProperty('ipcFd'), true); // should throw if stdio has ipc and sync is true var stdio2 = ['ipc', 'ipc', 'ipc']; -assert.throws(function() { - _validateStdio(stdio2, true); -}, /You cannot use IPC with synchronous forks/); +assert.throws(() => _validateStdio(stdio2, true), checkerr2); const stdio3 = [process.stdin, process.stdout, process.stderr]; var result = _validateStdio(stdio3, false); diff --git a/test/parallel/test-dgram-setTTL.js b/test/parallel/test-dgram-setTTL.js index 88627a314c3848..1a9255a501c6ee 100644 --- a/test/parallel/test-dgram-setTTL.js +++ b/test/parallel/test-dgram-setTTL.js @@ -4,14 +4,16 @@ const assert = require('assert'); const dgram = require('dgram'); const socket = dgram.createSocket('udp4'); +const regex = /^'arg' argument must be a\(n\) number/; + socket.bind(common.PORT); socket.on('listening', function() { var result = socket.setTTL(16); assert.strictEqual(result, 16); - assert.throws(function() { + assert.throws(() => { socket.setTTL('foo'); - }, /Argument must be a number/); + }, err => regex.test(err.message)); socket.close(); }); diff --git a/test/parallel/test-file-write-stream3.js b/test/parallel/test-file-write-stream3.js index c9473c26ddac0e..3503635acbcbfe 100644 --- a/test/parallel/test-file-write-stream3.js +++ b/test/parallel/test-file-write-stream3.js @@ -1,22 +1,21 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +const common = require('../common'); +const assert = require('assert'); -var path = require('path'), - fs = require('fs'); +const path = require('path'); +const fs = require('fs'); +const filepath = path.join(common.tmpDir, 'write_pos.txt'); -var filepath = path.join(common.tmpDir, 'write_pos.txt'); +const cb_expected = 'write open close write open close write open close '; +var cb_occurred = ''; -var cb_expected = 'write open close write open close write open close ', - cb_occurred = ''; +const fileDataInitial = 'abcdefghijklmnopqrstuvwxyz'; -var fileDataInitial = 'abcdefghijklmnopqrstuvwxyz'; - -var fileDataExpected_1 = 'abcdefghijklmnopqrstuvwxyz'; -var fileDataExpected_2 = 'abcdefghij123456qrstuvwxyz'; -var fileDataExpected_3 = 'abcdefghij\u2026\u2026qrstuvwxyz'; +const fileDataExpected_1 = 'abcdefghijklmnopqrstuvwxyz'; +const fileDataExpected_2 = 'abcdefghij123456qrstuvwxyz'; +const fileDataExpected_3 = 'abcdefghij\u2026\u2026qrstuvwxyz'; process.on('exit', function() { @@ -173,13 +172,10 @@ function run_test_4() { flags: 'r+' }; // Error: start must be >= zero - assert.throws( - function() { - file = fs.createWriteStream(filepath, options); - }, - /"start" must be/ - ); - + var regex = /^'start' must be >= zero/; + assert.throws(() => { + file = fs.createWriteStream(filepath, options); + }, err => regex.test(err.message)); } run_test_1(); diff --git a/test/parallel/test-fs-access.js b/test/parallel/test-fs-access.js index aafc32192d374a..c0ae6655a17a3b 100644 --- a/test/parallel/test-fs-access.js +++ b/test/parallel/test-fs-access.js @@ -1,11 +1,11 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var fs = require('fs'); -var path = require('path'); -var doesNotExist = __filename + '__this_should_not_exist'; -var readOnlyFile = path.join(common.tmpDir, 'read_only_file'); -var readWriteFile = path.join(common.tmpDir, 'read_write_file'); +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const doesNotExist = __filename + '__this_should_not_exist'; +const readOnlyFile = path.join(common.tmpDir, 'read_only_file'); +const readWriteFile = path.join(common.tmpDir, 'read_write_file'); var removeFile = function(file) { try { @@ -90,17 +90,19 @@ fs.access(readOnlyFile, fs.W_OK, function(err) { } }); -assert.throws(function() { - fs.access(100, fs.F_OK, function(err) {}); -}, /path must be a string/); +const regex1 = /^'callback' must be a function/; +const regex2 = /^path must be a string/i; +assert.throws(() => { + fs.access(100, fs.F_OK, err => {}); +}, err => regex2.test(err.message)); assert.throws(function() { fs.access(__filename, fs.F_OK); -}, /"callback" argument must be a function/); +}, err => regex1.test(err.message)); assert.throws(function() { fs.access(__filename, fs.F_OK, {}); -}, /"callback" argument must be a function/); +}, err => regex1.test(err.message)); assert.doesNotThrow(function() { fs.accessSync(__filename); diff --git a/test/parallel/test-fs-null-bytes.js b/test/parallel/test-fs-null-bytes.js index 1a6eb4ed71cb72..c95c8070b35e3a 100644 --- a/test/parallel/test-fs-null-bytes.js +++ b/test/parallel/test-fs-null-bytes.js @@ -1,18 +1,21 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var fs = require('fs'); +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); function check(async, sync) { - var expected = /Path must be a string without null bytes/; + var regex = /^'path' must be a string without null bytes/; + var expected = (err) => { + return regex.test(err.message); + }; var argsSync = Array.prototype.slice.call(arguments, 2); var argsAsync = argsSync.concat(function(er) { - assert(er && er.message.match(expected)); + assert(er && er.message.match(regex)); assert.equal(er.code, 'ENOENT'); }); if (sync) - assert.throws(function() { + assert.throws(() => { console.error(sync.name, argsSync); sync.apply(null, argsSync); }, expected); diff --git a/test/parallel/test-fs-read-buffer-tostring-fail.js b/test/parallel/test-fs-read-buffer-tostring-fail.js index 1276390aefb6f9..22255051c8be96 100644 --- a/test/parallel/test-fs-read-buffer-tostring-fail.js +++ b/test/parallel/test-fs-read-buffer-tostring-fail.js @@ -28,7 +28,7 @@ stream.on('finish', common.mustCall(function() { fd = fs.openSync(file, 'r'); fs.read(fd, kStringMaxLength + 1, 0, 'utf8', common.mustCall(function(err) { assert.ok(err instanceof Error); - assert.strictEqual('"toString()" failed', err.message); + assert(/'toString\(\)' failed/.test(err.message)); })); })); diff --git a/test/parallel/test-fs-read-stream-inherit.js b/test/parallel/test-fs-read-stream-inherit.js index a83e8583c7626a..c2abc5185ec8bc 100644 --- a/test/parallel/test-fs-read-stream-inherit.js +++ b/test/parallel/test-fs-read-stream-inherit.js @@ -1,17 +1,17 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +const common = require('../common'); +const assert = require('assert'); -var path = require('path'); -var fs = require('fs'); -var fn = path.join(common.fixturesDir, 'elipses.txt'); -var rangeFile = path.join(common.fixturesDir, 'x.txt'); +const path = require('path'); +const fs = require('fs'); +const fn = path.join(common.fixturesDir, 'elipses.txt'); +const rangeFile = path.join(common.fixturesDir, 'x.txt'); -var callbacks = { open: 0, end: 0, close: 0 }; +const callbacks = { open: 0, end: 0, close: 0 }; var paused = false; -var file = fs.ReadStream(fn); +const file = fs.ReadStream(fn); file.on('open', function(fd) { file.length = 0; @@ -112,9 +112,11 @@ file6.on('end', function() { assert.equal(file6.data, 'yz\n'); }); -assert.throws(function() { +const regex = /^'start' option must be <= 'end' option/; + +assert.throws(() => { fs.createReadStream(rangeFile, Object.create({start: 10, end: 2})); -}, /"start" option must be <= "end" option/); +}, err => regex.test(err.message)); var stream = fs.createReadStream(rangeFile, Object.create({ start: 0, end: 0 })); diff --git a/test/parallel/test-fs-read-stream-throw-type-error.js b/test/parallel/test-fs-read-stream-throw-type-error.js index 81f924d355b91c..ad65544801734b 100644 --- a/test/parallel/test-fs-read-stream-throw-type-error.js +++ b/test/parallel/test-fs-read-stream-throw-type-error.js @@ -6,28 +6,30 @@ const path = require('path'); const example = path.join(common.fixturesDir, 'x.txt'); -assert.doesNotThrow(function() { +const regex = /^'options' argument must be a string or object/; + +assert.doesNotThrow(() => { fs.createReadStream(example, undefined); }); -assert.doesNotThrow(function() { +assert.doesNotThrow(() => { fs.createReadStream(example, 'utf8'); }); -assert.doesNotThrow(function() { +assert.doesNotThrow(() => { fs.createReadStream(example, {encoding: 'utf8'}); }); -assert.throws(function() { +assert.throws(() => { fs.createReadStream(example, null); -}, /"options" argument must be a string or an object/); -assert.throws(function() { +}, err => regex.test(err.message)); +assert.throws(() => { fs.createReadStream(example, 123); -}, /"options" argument must be a string or an object/); -assert.throws(function() { +}, err => regex.test(err.message)); +assert.throws(() => { fs.createReadStream(example, 0); -}, /"options" argument must be a string or an object/); -assert.throws(function() { +}, err => regex.test(err.message)); +assert.throws(() => { fs.createReadStream(example, true); -}, /"options" argument must be a string or an object/); -assert.throws(function() { +}, err => regex.test(err.message)); +assert.throws(() => { fs.createReadStream(example, false); -}, /"options" argument must be a string or an object/); +}, err => regex.test(err.message)); diff --git a/test/parallel/test-fs-read-stream.js b/test/parallel/test-fs-read-stream.js index 8bfb6eb2b2c62c..6a2efeee2f5def 100644 --- a/test/parallel/test-fs-read-stream.js +++ b/test/parallel/test-fs-read-stream.js @@ -105,9 +105,11 @@ file6.on('end', function() { assert.equal(file6.data, 'yz\n'); }); -assert.throws(function() { +const regex = /^'start' option must be <= 'end' option/; + +assert.throws(() => { fs.createReadStream(rangeFile, {start: 10, end: 2}); -}, /"start" option must be <= "end" option/); +}, err => regex.test(err.message)); var stream = fs.createReadStream(rangeFile, { start: 0, end: 0 }); stream.data = ''; diff --git a/test/parallel/test-fs-readfile-tostring-fail.js b/test/parallel/test-fs-readfile-tostring-fail.js index 272aa865643e53..aeaf1fe9e3e72a 100644 --- a/test/parallel/test-fs-readfile-tostring-fail.js +++ b/test/parallel/test-fs-readfile-tostring-fail.js @@ -25,7 +25,7 @@ stream.on('finish', common.mustCall(function() { // make sure that the toString does not throw an error fs.readFile(file, 'utf8', common.mustCall(function(err, buf) { assert.ok(err instanceof Error); - assert.strictEqual('"toString()" failed', err.message); + assert(/'toString\(\)' failed/.test(err.message)); })); })); diff --git a/test/parallel/test-fs-watchfile.js b/test/parallel/test-fs-watchfile.js index d30261859c39b7..8d1ea470ab54b6 100644 --- a/test/parallel/test-fs-watchfile.js +++ b/test/parallel/test-fs-watchfile.js @@ -5,18 +5,21 @@ const fs = require('fs'); const path = require('path'); const assert = require('assert'); +const regex1 = /^'listener' must be a function/; +const regex2 = /^'path' argument must be a\(n\) string/; + // Basic usage tests. -assert.throws(function() { +assert.throws(() => { fs.watchFile('./some-file'); -}, /"watchFile\(\)" requires a listener function/); +}, err => regex1.test(err.message)); -assert.throws(function() { +assert.throws(() => { fs.watchFile('./another-file', {}, 'bad listener'); -}, /"watchFile\(\)" requires a listener function/); +}, err => regex1.test(err.message)); -assert.throws(function() { - fs.watchFile(new Object(), function() {}); -}, /Path must be a string/); +assert.throws(() => { + fs.watchFile(new Object(), () => {}); +}, err => regex2.test(err.message)); const enoentFile = path.join(common.tmpDir, 'non-existent-file'); const expectedStatObject = new fs.Stats( diff --git a/test/parallel/test-fs-write-stream-throw-type-error.js b/test/parallel/test-fs-write-stream-throw-type-error.js index 007ac03f1bb342..edc4731b502299 100644 --- a/test/parallel/test-fs-write-stream-throw-type-error.js +++ b/test/parallel/test-fs-write-stream-throw-type-error.js @@ -6,30 +6,32 @@ const path = require('path'); const example = path.join(common.tmpDir, 'dummy'); +const regex = /^'options' argument must be a string or object/; + common.refreshTmpDir(); -assert.doesNotThrow(function() { +assert.doesNotThrow(() => { fs.createWriteStream(example, undefined); }); -assert.doesNotThrow(function() { +assert.doesNotThrow(() => { fs.createWriteStream(example, 'utf8'); }); -assert.doesNotThrow(function() { +assert.doesNotThrow(() => { fs.createWriteStream(example, {encoding: 'utf8'}); }); -assert.throws(function() { +assert.throws(() => { fs.createWriteStream(example, null); -}, /"options" argument must be a string or an object/); -assert.throws(function() { +}, err => regex.test(err.message)); +assert.throws(() => { fs.createWriteStream(example, 123); -}, /"options" argument must be a string or an object/); -assert.throws(function() { +}, err => regex.test(err.message)); +assert.throws(() => { fs.createWriteStream(example, 0); -}, /"options" argument must be a string or an object/); -assert.throws(function() { +}, err => regex.test(err.message)); +assert.throws(() => { fs.createWriteStream(example, true); -}, /"options" argument must be a string or an object/); -assert.throws(function() { +}, err => regex.test(err.message)); +assert.throws(() => { fs.createWriteStream(example, false); -}, /"options" argument must be a string or an object/); +}, err => regex.test(err.message)); diff --git a/test/parallel/test-http-agent-keepalive.js b/test/parallel/test-http-agent-keepalive.js index 6800e893e329da..afbe39d4403e04 100644 --- a/test/parallel/test-http-agent-keepalive.js +++ b/test/parallel/test-http-agent-keepalive.js @@ -89,7 +89,7 @@ function remoteError() { }); req.on('error', function(err) { assert.ok(err); - assert.equal(err.message, 'socket hang up'); + assert(/socket hang up/.test(err.message)); assert.equal(agent.sockets[name].length, 1); assert.equal(agent.freeSockets[name], undefined); // Wait socket 'close' event emit diff --git a/test/parallel/test-http-res-write-after-end.js b/test/parallel/test-http-res-write-after-end.js index 206f4273ec70c7..4cf1a4ef9f4ec0 100644 --- a/test/parallel/test-http-res-write-after-end.js +++ b/test/parallel/test-http-res-write-after-end.js @@ -25,5 +25,5 @@ server.listen(common.PORT, function() { process.on('exit', function onProcessExit(code) { assert(responseError, 'response should have emitted error'); - assert.equal(responseError.message, 'write after end'); + assert(/^write after end/.test(responseError.message)); }); diff --git a/test/parallel/test-http-unix-socket.js b/test/parallel/test-http-unix-socket.js index bdac0566c33a42..28ffc62eaa80ac 100644 --- a/test/parallel/test-http-unix-socket.js +++ b/test/parallel/test-http-unix-socket.js @@ -1,7 +1,7 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var http = require('http'); +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); var status_ok = false; // status code == 200? var headers_ok = false; @@ -46,7 +46,7 @@ server.listen(common.PIPE, function() { server.close(function(error) { assert.equal(error, undefined); server.close(function(error) { - assert.equal(error && error.message, 'Not running'); + assert(error && /^Not running/.test(error.message)); }); }); }); diff --git a/test/parallel/test-http-url.parse-only-support-http-https-protocol.js b/test/parallel/test-http-url.parse-only-support-http-https-protocol.js index e7ed82817146ea..a52e6bc0bfbab6 100644 --- a/test/parallel/test-http-url.parse-only-support-http-https-protocol.js +++ b/test/parallel/test-http-url.parse-only-support-http-https-protocol.js @@ -1,66 +1,46 @@ 'use strict'; require('../common'); -var assert = require('assert'); -var http = require('http'); -var url = require('url'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); +const tests = [ + [ + 'file:///whatever', + /^Protocol 'file:' not supported. Expected 'http:'/ + ], + [ + 'mailto:asdf@asdf.com', + /^Protocol 'mailto:' not supported. Expected 'http:'/ + ], + [ + 'ftp://www.example.com', + /^Protocol 'ftp:' not supported. Expected 'http:'/ + ], + [ + 'javascript:alert(\'hello\');', + /^Protocol 'javascript:' not supported. Expected 'http:'/ + ], + [ + 'xmpp:isaacschlueter@jabber.org', + /^Protocol 'xmpp:' not supported. Expected 'http:'/ + ], + [ + 'f://some.host/path', + /^Protocol 'f:' not supported. Expected 'http:'/ + ] +]; -assert.throws(function() { - http.request(url.parse('file:///whatever')); -}, function(err) { - if (err instanceof Error) { - assert.strictEqual(err.message, 'Protocol "file:" not supported.' + - ' Expected "http:"'); - return true; - } -}); - -assert.throws(function() { - http.request(url.parse('mailto:asdf@asdf.com')); -}, function(err) { - if (err instanceof Error) { - assert.strictEqual(err.message, 'Protocol "mailto:" not supported.' + - ' Expected "http:"'); - return true; - } -}); - -assert.throws(function() { - http.request(url.parse('ftp://www.example.com')); -}, function(err) { - if (err instanceof Error) { - assert.strictEqual(err.message, 'Protocol "ftp:" not supported.' + - ' Expected "http:"'); - return true; - } -}); - -assert.throws(function() { - http.request(url.parse('javascript:alert(\'hello\');')); -}, function(err) { - if (err instanceof Error) { - assert.strictEqual(err.message, 'Protocol "javascript:" not supported.' + - ' Expected "http:"'); - return true; - } -}); - -assert.throws(function() { - http.request(url.parse('xmpp:isaacschlueter@jabber.org')); -}, function(err) { - if (err instanceof Error) { - assert.strictEqual(err.message, 'Protocol "xmpp:" not supported.' + - ' Expected "http:"'); - return true; - } -}); - -assert.throws(function() { - http.request(url.parse('f://some.host/path')); -}, function(err) { - if (err instanceof Error) { - assert.strictEqual(err.message, 'Protocol "f:" not supported.' + - ' Expected "http:"'); - return true; - } -}); +for (var test of tests) { + assert.throws( + () => { + http.request(url.parse(test[0])); + }, + (err) => { + if (err instanceof Error) { + assert(test[1].test(err.message)); + return true; + } + } + ); +} diff --git a/test/parallel/test-http-write-head.js b/test/parallel/test-http-write-head.js index a56d6f18d0e377..03a4e38e40887b 100644 --- a/test/parallel/test-http-write-head.js +++ b/test/parallel/test-http-write-head.js @@ -25,7 +25,8 @@ var s = http.createServer(function(req, res) { res.setHeader('foo', undefined); } catch (e) { assert.ok(e instanceof Error); - assert.equal(e.message, '"value" required in setHeader("foo", value)'); + console.log(e.message); + assert(/^'value' argument is required/.test(e.message)); threw = true; } assert.ok(threw, 'Undefined value should throw'); diff --git a/test/parallel/test-https-strict.js b/test/parallel/test-https-strict.js index 04561959de130f..0e605d9aa8b23e 100644 --- a/test/parallel/test-https-strict.js +++ b/test/parallel/test-https-strict.js @@ -2,17 +2,17 @@ // disable strict server certificate validation by the client process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; -var common = require('../common'); -var assert = require('assert'); +const common = require('../common'); +const assert = require('assert'); if (!common.hasCrypto) { console.log('1..0 # Skipped: missing crypto'); return; } -var https = require('https'); +const https = require('https'); -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); function file(fname) { return path.resolve(common.fixturesDir, 'keys', fname); @@ -141,7 +141,8 @@ function makeReq(path, port, error, host, ca) { req.on('response', function(res) { responseCount++; - assert.equal(res.connection.authorizationError, error); + if (error) + assert(error.test(res.connection.authorizationError)); responseErrors[path] = res.connection.authorizationError; pending--; if (pending === 0) { @@ -153,46 +154,38 @@ function makeReq(path, port, error, host, ca) { }); } +const ERR_PREFIX = `^Hostname/IP doesn't match certificate's altnames: `; +const regex = new RegExp( + `${ERR_PREFIX}'Host: localhost\\. is not cert's CN: agent1'`); +const regex4 = new RegExp( + `${ERR_PREFIX}'Host: localhost\\. is not cert's CN: agent3'`); +const regex2 = /^UNABLE_TO_VERIFY_LEAF_SIGNATURE/; +const regex3 = /^DEPTH_ZERO_SELF_SIGNED_CERT/; + function allListening() { // ok, ready to start the tests! // server1: host 'agent1', signed by ca1 - makeReq('/inv1', port1, 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'); - makeReq('/inv1-ca1', port1, - 'Hostname/IP doesn\'t match certificate\'s altnames: ' + - '"Host: localhost. is not cert\'s CN: agent1"', - null, ca1); - makeReq('/inv1-ca1ca2', port1, - 'Hostname/IP doesn\'t match certificate\'s altnames: ' + - '"Host: localhost. is not cert\'s CN: agent1"', - null, [ca1, ca2]); + makeReq('/inv1', port1, regex2); + makeReq('/inv1-ca1', port1, regex, null, ca1); + makeReq('/inv1-ca1ca2', port1, regex, null, [ca1, ca2]); makeReq('/val1-ca1', port1, null, 'agent1', ca1); makeReq('/val1-ca1ca2', port1, null, 'agent1', [ca1, ca2]); - makeReq('/inv1-ca2', port1, - 'UNABLE_TO_VERIFY_LEAF_SIGNATURE', 'agent1', ca2); + makeReq('/inv1-ca2', port1, regex2, 'agent1', ca2); // server2: self-signed, host = 'agent2' // doesn't matter that thename matches, all of these will error. - makeReq('/inv2', port2, 'DEPTH_ZERO_SELF_SIGNED_CERT'); - makeReq('/inv2-ca1', port2, 'DEPTH_ZERO_SELF_SIGNED_CERT', - 'agent2', ca1); - makeReq('/inv2-ca1ca2', port2, 'DEPTH_ZERO_SELF_SIGNED_CERT', - 'agent2', [ca1, ca2]); + makeReq('/inv2', port2, regex3); + makeReq('/inv2-ca1', port2, regex3, 'agent2', ca1); + makeReq('/inv2-ca1ca2', port2, regex3, 'agent2', [ca1, ca2]); // server3: host 'agent3', signed by ca2 - makeReq('/inv3', port3, 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'); - makeReq('/inv3-ca2', port3, - 'Hostname/IP doesn\'t match certificate\'s altnames: ' + - '"Host: localhost. is not cert\'s CN: agent3"', - null, ca2); - makeReq('/inv3-ca1ca2', port3, - 'Hostname/IP doesn\'t match certificate\'s altnames: ' + - '"Host: localhost. is not cert\'s CN: agent3"', - null, [ca1, ca2]); + makeReq('/inv3', port3, regex2); + makeReq('/inv3-ca2', port3, regex4, null, ca2); + makeReq('/inv3-ca1ca2', port3, regex4, null, [ca1, ca2]); makeReq('/val3-ca2', port3, null, 'agent3', ca2); makeReq('/val3-ca1ca2', port3, null, 'agent3', [ca1, ca2]); - makeReq('/inv3-ca1', port3, - 'UNABLE_TO_VERIFY_LEAF_SIGNATURE', 'agent1', ca1); + makeReq('/inv3-ca1', port3, regex2, 'agent1', ca1); } diff --git a/test/parallel/test-internal-messages.js b/test/parallel/test-internal-messages.js new file mode 100644 index 00000000000000..6e8b888bc9fffb --- /dev/null +++ b/test/parallel/test-internal-messages.js @@ -0,0 +1,36 @@ +'use strict'; +// Flags: --expose_internals + +require('../common'); +const assert = require('assert'); +const I18N = require('internal/messages'); + +assert(I18N); +assert(I18N(I18N.ASSERTION_ERROR)); +assert(I18N.messages); +assert(I18N.keys); +assert.equal(I18N.messages.length, I18N.keys.length); + +const val = I18N(I18N.FUNCTION_REQUIRED, 'foo'); +assert(/foo/.test(val)); + +assert.throws(() => { + throw new I18N.Error(I18N.ASSERTION_ERROR); +}, Error); + +assert.throws(() => { + throw new I18N.TypeError(I18N.ASSERTION_ERROR); +}, TypeError); + +assert.throws(() => { + throw new I18N.RangeError(I18N.ASSERTION_ERROR); +}, RangeError); + +assert(/ASSERTION_ERROR/.test( + new I18N.Error(I18N.ASSERTION_ERROR).message)); + +// Verify the error properties +const err = new I18N.Error(I18N.ASSERTION_ERROR, 'foo'); +assert.equal(err.key, I18N.keys[I18N.ASSERTION_ERROR]); +assert.equal(err.args.length, 1); +assert.equal(err.args[0], 'foo'); diff --git a/test/parallel/test-module-loading-error.js b/test/parallel/test-module-loading-error.js index 072a6aadcb8c62..592498e479c5ea 100644 --- a/test/parallel/test-module-loading-error.js +++ b/test/parallel/test-module-loading-error.js @@ -1,6 +1,6 @@ 'use strict'; require('../common'); -var assert = require('assert'); +const assert = require('assert'); console.error('load test-module-loading-error.js'); @@ -28,11 +28,11 @@ try { try { require(); } catch (e) { - assert.notEqual(e.toString().indexOf('missing path'), -1); + assert(/^missing path/.test(e.message)); } try { require({}); } catch (e) { - assert.notEqual(e.toString().indexOf('path must be a string'), -1); + assert(/^path must be a string/.test(e.message)); } diff --git a/test/parallel/test-net-create-connection.js b/test/parallel/test-net-create-connection.js index 44ae62b343736b..f451c5f59b047a 100644 --- a/test/parallel/test-net-create-connection.js +++ b/test/parallel/test-net-create-connection.js @@ -1,10 +1,10 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var net = require('net'); +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); -var tcpPort = common.PORT; -var expectedConnections = 7; +const tcpPort = common.PORT; +const expectedConnections = 7; var clientConnected = 0; var serverConnected = 0; @@ -15,17 +15,18 @@ var server = net.createServer(function(socket) { } }); +const regex1 = /^'port' argument must be a string or number/; +const regex2 = /^Port should be > 0 and < 65536/; + server.listen(tcpPort, 'localhost', function() { function cb() { ++clientConnected; } function fail(opts, errtype, msg) { - assert.throws(function() { + assert.throws(() => { net.createConnection(opts, cb); - }, function(err) { - return err instanceof errtype && msg === err.message; - }); + }, err => err instanceof errtype && msg.test(err.message)); } net.createConnection(tcpPort).on('connect', cb); @@ -38,55 +39,55 @@ server.listen(tcpPort, 'localhost', function() { fail({ port: true - }, TypeError, '"port" option should be a number or string: true'); + }, TypeError, regex1); fail({ port: false - }, TypeError, '"port" option should be a number or string: false'); + }, TypeError, regex1); fail({ port: [] - }, TypeError, '"port" option should be a number or string: '); + }, TypeError, regex1); fail({ port: {} - }, TypeError, '"port" option should be a number or string: [object Object]'); + }, TypeError, regex1); fail({ port: null - }, TypeError, '"port" option should be a number or string: null'); + }, TypeError, regex1); fail({ port: '' - }, RangeError, '"port" option should be >= 0 and < 65536: '); + }, RangeError, regex2); fail({ port: ' ' - }, RangeError, '"port" option should be >= 0 and < 65536: '); + }, RangeError, regex2); fail({ port: '0x' - }, RangeError, '"port" option should be >= 0 and < 65536: 0x'); + }, RangeError, regex2); fail({ port: '-0x1' - }, RangeError, '"port" option should be >= 0 and < 65536: -0x1'); + }, RangeError, regex2); fail({ port: NaN - }, RangeError, '"port" option should be >= 0 and < 65536: NaN'); + }, RangeError, regex2); fail({ port: Infinity - }, RangeError, '"port" option should be >= 0 and < 65536: Infinity'); + }, RangeError, regex2); fail({ port: -1 - }, RangeError, '"port" option should be >= 0 and < 65536: -1'); + }, RangeError, regex2); fail({ port: 65536 - }, RangeError, '"port" option should be >= 0 and < 65536: 65536'); + }, RangeError, regex2); }); // Try connecting to random ports, but do so once the server is closed diff --git a/test/parallel/test-net-listen-port-option.js b/test/parallel/test-net-listen-port-option.js index fb568cf5206942..8f021a05e4dfe4 100644 --- a/test/parallel/test-net-listen-port-option.js +++ b/test/parallel/test-net-listen-port-option.js @@ -1,12 +1,15 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var net = require('net'); +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); function close() { this.close(); } net.Server().listen({ port: undefined }, close); net.Server().listen({ port: '' + common.PORT }, close); +const regex1 = /^Port should be > 0 and < 65536/; +const regex2 = /^Invalid listen argument/; + [ 'nan', -1, 123.456, @@ -14,14 +17,14 @@ net.Server().listen({ port: '' + common.PORT }, close); 1 / 0, -1 / 0, '+Infinity', - '-Infinity' ].forEach(function(port) { - assert.throws(function() { - net.Server().listen({ port: port }, assert.fail); - }, /"port" option should be >= 0 and < 65536/i); -}); + '-Infinity' ].forEach((port) => { + assert.throws(() => { + net.Server().listen({ port: port }, assert.fail); + }, err => regex1.test(err.message)); + }); -[null, true, false].forEach(function(port) { - assert.throws(function() { +[null, true, false].forEach((port) => { + assert.throws(() => { net.Server().listen({ port: port }, assert.fail); - }, /invalid listen argument/i); + }, err => regex2.test(err.message)); }); diff --git a/test/parallel/test-path-parse-format.js b/test/parallel/test-path-parse-format.js index af1d993ffd3a9f..22c870338b959b 100644 --- a/test/parallel/test-path-parse-format.js +++ b/test/parallel/test-path-parse-format.js @@ -54,25 +54,28 @@ const unixSpecialCaseFormatTests = [ [{}, ''] ]; +const regex1 = /^'path' argument must be a\(n\) string/; +const regex2 = /^'pathObject' argument must be a\(n\) object/; + const errors = [ {method: 'parse', input: [null], - message: /Path must be a string. Received null/}, + message: regex1}, {method: 'parse', input: [{}], - message: /Path must be a string. Received {}/}, + message: regex1}, {method: 'parse', input: [true], - message: /Path must be a string. Received true/}, + message: regex1}, {method: 'parse', input: [1], - message: /Path must be a string. Received 1/}, + message: regex1}, {method: 'parse', input: [], - message: /Path must be a string. Received undefined/}, + message: regex1}, {method: 'format', input: [null], - message: /Parameter "pathObject" must be an object, not/}, + message: regex2}, {method: 'format', input: [''], - message: /Parameter "pathObject" must be an object, not string/}, + message: regex2}, {method: 'format', input: [true], - message: /Parameter "pathObject" must be an object, not boolean/}, + message: regex2}, {method: 'format', input: [1], - message: /Parameter "pathObject" must be an object, not number/}, + message: regex2}, ]; checkParseFormat(path.win32, winPaths); @@ -88,10 +91,7 @@ function checkErrors(path) { path[errorCase.method].apply(path, errorCase.input); } catch(err) { assert.ok(err instanceof TypeError); - assert.ok( - errorCase.message.test(err.message), - 'expected ' + errorCase.message + ' to match ' + err.message - ); + assert(errorCase.message.test(err.message)); return; } diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js index 0c0340e037a4e4..11ffe70bad41e6 100644 --- a/test/parallel/test-readline-interface.js +++ b/test/parallel/test-readline-interface.js @@ -1,9 +1,9 @@ 'use strict'; require('../common'); -var assert = require('assert'); -var readline = require('readline'); -var EventEmitter = require('events').EventEmitter; -var inherits = require('util').inherits; +const assert = require('assert'); +const readline = require('readline'); +const EventEmitter = require('events'); +const inherits = require('util').inherits; function FakeInput() { EventEmitter.call(this); @@ -215,14 +215,14 @@ function isWarned(emitter) { // constructor throws if completer is not a function or undefined fi = new FakeInput(); - assert.throws(function() { + assert.throws(() => { readline.createInterface({ input: fi, completer: 'string is not valid' }); - }, function(err) { + }, (err) => { if (err instanceof TypeError) { - if (/Argument "completer" must be a function/.test(err)) { + if (/^'completer' must be a function/.test(err.message)) { return true; } } diff --git a/test/parallel/test-stream2-writable.js b/test/parallel/test-stream2-writable.js index 81e57d06eb3bec..af7552513e7069 100644 --- a/test/parallel/test-stream2-writable.js +++ b/test/parallel/test-stream2-writable.js @@ -309,7 +309,7 @@ test('end(chunk) two times is an error', function(t) { var gotError = false; w.on('error', function(er) { gotError = true; - t.equal(er.message, 'write after end'); + assert(/^write after end/.test(er.message)); }); w.end('this is the end'); w.end('and so is this'); diff --git a/test/parallel/test-stringbytes-external-exceed-max-by-1-ascii.js b/test/parallel/test-stringbytes-external-exceed-max-by-1-ascii.js index 46590cd492fa14..42e5836e9a6cb9 100644 --- a/test/parallel/test-stringbytes-external-exceed-max-by-1-ascii.js +++ b/test/parallel/test-stringbytes-external-exceed-max-by-1-ascii.js @@ -28,6 +28,8 @@ try { return; } -assert.throws(function() { +const erregex = /^'toString\(\)' failed/; + +assert.throws(() => { buf.toString('ascii'); -}, /"toString\(\)" failed/); +}, err => erregex.test(err.message)); diff --git a/test/parallel/test-stringbytes-external-exceed-max-by-1-base64.js b/test/parallel/test-stringbytes-external-exceed-max-by-1-base64.js index 905f4ac9731796..3d21158e1df40d 100644 --- a/test/parallel/test-stringbytes-external-exceed-max-by-1-base64.js +++ b/test/parallel/test-stringbytes-external-exceed-max-by-1-base64.js @@ -28,6 +28,8 @@ try { return; } -assert.throws(function() { +const erregex = /^'toString\(\)' failed/; + +assert.throws(() => { buf.toString('base64'); -}, /"toString\(\)" failed/); +}, err => erregex.test(err.message)); diff --git a/test/parallel/test-stringbytes-external-exceed-max-by-1-binary.js b/test/parallel/test-stringbytes-external-exceed-max-by-1-binary.js index 9564af08de2752..e6c86ba6def4a2 100644 --- a/test/parallel/test-stringbytes-external-exceed-max-by-1-binary.js +++ b/test/parallel/test-stringbytes-external-exceed-max-by-1-binary.js @@ -28,9 +28,11 @@ try { return; } -assert.throws(function() { +const erregex = /^'toString\(\)' failed/; + +assert.throws(() => { buf.toString('binary'); -}, /"toString\(\)" failed/); +}, err => erregex.test(err.message)); var maxString = buf.toString('binary', 1); assert.equal(maxString.length, kStringMaxLength); diff --git a/test/parallel/test-stringbytes-external-exceed-max-by-1-hex.js b/test/parallel/test-stringbytes-external-exceed-max-by-1-hex.js index 1ca75403c243a7..547a1ac2748fb3 100644 --- a/test/parallel/test-stringbytes-external-exceed-max-by-1-hex.js +++ b/test/parallel/test-stringbytes-external-exceed-max-by-1-hex.js @@ -28,6 +28,8 @@ try { return; } -assert.throws(function() { +const erregex = /^'toString\(\)' failed/; + +assert.throws(() => { buf.toString('hex'); -}, /"toString\(\)" failed/); +}, err => erregex.test(err.message)); diff --git a/test/parallel/test-stringbytes-external-exceed-max-by-1-utf8.js b/test/parallel/test-stringbytes-external-exceed-max-by-1-utf8.js index 5e4bca5c9a56e8..b26b5a87dcfa0e 100644 --- a/test/parallel/test-stringbytes-external-exceed-max-by-1-utf8.js +++ b/test/parallel/test-stringbytes-external-exceed-max-by-1-utf8.js @@ -28,10 +28,13 @@ try { return; } -assert.throws(function() { +const erregex1 = /^'toString\(\)' failed|^Invalid array buffer length/; +const erregex2 = /^'toString\(\)' failed/; + +assert.throws(() => { buf.toString(); -}, /"toString\(\)" failed|Invalid array buffer length/); +}, (err) => erregex1.test(err.message)); -assert.throws(function() { +assert.throws(() => { buf.toString('utf8'); -}, /"toString\(\)" failed/); +}, err => erregex2.test(err.message)); diff --git a/test/parallel/test-stringbytes-external-exceed-max.js b/test/parallel/test-stringbytes-external-exceed-max.js index 33bc2eaee7cb5c..cd4d524b628177 100644 --- a/test/parallel/test-stringbytes-external-exceed-max.js +++ b/test/parallel/test-stringbytes-external-exceed-max.js @@ -28,6 +28,8 @@ try { return; } -assert.throws(function() { +const erregex = /^'toString\(\)' failed/; + +assert.throws(() => { buf.toString('utf16le'); -}, /"toString\(\)" failed/); +}, err => erregex.test(err.message)); diff --git a/test/parallel/test-timers-throw-when-cb-not-function.js b/test/parallel/test-timers-throw-when-cb-not-function.js index 13533107934bd6..fc91043128a976 100644 --- a/test/parallel/test-timers-throw-when-cb-not-function.js +++ b/test/parallel/test-timers-throw-when-cb-not-function.js @@ -8,18 +8,16 @@ function doSetTimeout(callback, after) { }; } -assert.throws(doSetTimeout('foo'), - /"callback" argument must be a function/); -assert.throws(doSetTimeout({foo: 'bar'}), - /"callback" argument must be a function/); -assert.throws(doSetTimeout(), - /"callback" argument must be a function/); -assert.throws(doSetTimeout(undefined, 0), - /"callback" argument must be a function/); -assert.throws(doSetTimeout(null, 0), - /"callback" argument must be a function/); -assert.throws(doSetTimeout(false, 0), - /"callback" argument must be a function/); +function checkErr(err) { + return /^'callback' must be a function/.test(err.message); +} + +assert.throws(doSetTimeout('foo'), checkErr); +assert.throws(doSetTimeout({foo: 'bar'}), checkErr); +assert.throws(doSetTimeout(), checkErr); +assert.throws(doSetTimeout(undefined, 0), checkErr); +assert.throws(doSetTimeout(null, 0), checkErr); +assert.throws(doSetTimeout(false, 0), checkErr); function doSetInterval(callback, after) { @@ -28,18 +26,12 @@ function doSetInterval(callback, after) { }; } -assert.throws(doSetInterval('foo'), - /"callback" argument must be a function/); -assert.throws(doSetInterval({foo: 'bar'}), - /"callback" argument must be a function/); -assert.throws(doSetInterval(), - /"callback" argument must be a function/); -assert.throws(doSetInterval(undefined, 0), - /"callback" argument must be a function/); -assert.throws(doSetInterval(null, 0), - /"callback" argument must be a function/); -assert.throws(doSetInterval(false, 0), - /"callback" argument must be a function/); +assert.throws(doSetInterval('foo'), checkErr); +assert.throws(doSetInterval({foo: 'bar'}), checkErr); +assert.throws(doSetInterval(), checkErr); +assert.throws(doSetInterval(undefined, 0), checkErr); +assert.throws(doSetInterval(null, 0), checkErr); +assert.throws(doSetInterval(false, 0), checkErr); function doSetImmediate(callback, after) { @@ -48,15 +40,9 @@ function doSetImmediate(callback, after) { }; } -assert.throws(doSetImmediate('foo'), - /"callback" argument must be a function/); -assert.throws(doSetImmediate({foo: 'bar'}), - /"callback" argument must be a function/); -assert.throws(doSetImmediate(), - /"callback" argument must be a function/); -assert.throws(doSetImmediate(undefined, 0), - /"callback" argument must be a function/); -assert.throws(doSetImmediate(null, 0), - /"callback" argument must be a function/); -assert.throws(doSetImmediate(false, 0), - /"callback" argument must be a function/); +assert.throws(doSetImmediate('foo'), checkErr); +assert.throws(doSetImmediate({foo: 'bar'}), checkErr); +assert.throws(doSetImmediate(), checkErr); +assert.throws(doSetImmediate(undefined, 0), checkErr); +assert.throws(doSetImmediate(null, 0), checkErr); +assert.throws(doSetImmediate(false, 0), checkErr); diff --git a/test/parallel/test-tls-client-mindhsize.js b/test/parallel/test-tls-client-mindhsize.js index a67a3cd67d983b..8b5bd8c40f914a 100644 --- a/test/parallel/test-tls-client-mindhsize.js +++ b/test/parallel/test-tls-client-mindhsize.js @@ -1,16 +1,16 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +const common = require('../common'); +const assert = require('assert'); if (!common.hasCrypto) { console.log('1..0 # Skipped: missing crypto'); process.exit(); } -var tls = require('tls'); +const tls = require('tls'); -var fs = require('fs'); -var key = fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'); -var cert = fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'); +const fs = require('fs'); +const key = fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'); +const cert = fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'); var nsuccess = 0; var nerror = 0; @@ -53,8 +53,7 @@ function test(size, err, next) { if (err) { client.on('error', function(e) { nerror++; - assert.strictEqual(e.message, 'DH parameter size 1024 is less' - + ' than 2048'); + assert(/^DH parameter size 1024 is less than 2048/.test(e.message)); server.close(); }); } diff --git a/test/parallel/test-tls-sni-option.js b/test/parallel/test-tls-sni-option.js index cbd46c46fef291..626a235930f58b 100644 --- a/test/parallel/test-tls-sni-option.js +++ b/test/parallel/test-tls-sni-option.js @@ -5,15 +5,15 @@ if (!process.features.tls_sni) { return; } -var common = require('../common'), - assert = require('assert'), - fs = require('fs'); +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); if (!common.hasCrypto) { console.log('1..0 # Skipped: missing crypto'); return; } -var tls = require('tls'); +const tls = require('tls'); function filenamePEM(n) { return require('path').join(common.fixturesDir, 'keys', n + '.pem'); @@ -162,8 +162,11 @@ process.on('exit', function() { null ]); assert.deepEqual(clientResults, [true, true, true, false, false]); - assert.deepEqual(clientErrors, [null, null, null, null, 'socket hang up']); - assert.deepEqual(serverErrors, [ - null, null, null, null, 'Invalid SNI context' - ]); + + assert.deepEqual(clientErrors.slice(0, 4), [null, null, null, null]); + assert(/^socket hang up/.test(clientErrors[4])); + + assert.deepEqual(serverErrors.slice(0, 4), [null, null, null, null]); + assert(/^Invalid SNI context/.test(serverErrors[4])); + }); diff --git a/test/parallel/test-tty-stdout-end.js b/test/parallel/test-tty-stdout-end.js index a33a2e5ed27209..0046011b52e25c 100644 --- a/test/parallel/test-tty-stdout-end.js +++ b/test/parallel/test-tty-stdout-end.js @@ -9,7 +9,7 @@ const shouldThrow = function() { const validateError = function(e) { return e instanceof Error && - e.message === 'process.stdout cannot be closed.'; + /^process.stdout cannot be closed/.test(e.message); }; assert.throws(shouldThrow, validateError); diff --git a/test/parallel/test-writeuint.js b/test/parallel/test-writeuint.js index 20d9d7dcefe063..12b1d00ff94c2e 100644 --- a/test/parallel/test-writeuint.js +++ b/test/parallel/test-writeuint.js @@ -124,17 +124,18 @@ function test32(clazz) { function testUint(clazz) { const data = new clazz(8); + const erregex = /^'value' argument is out of bounds/; var val = 1; // Test 0 to 5 bytes. for (var i = 0; i <= 5; i++) { const errmsg = `byteLength: ${i}`; - ASSERT.throws(function() { + ASSERT.throws(() => { data.writeUIntBE(val, 0, i); - }, /"value" argument is out of bounds/, errmsg); - ASSERT.throws(function() { + }, err => erregex.test(err.message), errmsg); + ASSERT.throws(() => { data.writeUIntLE(val, 0, i); - }, /"value" argument is out of bounds/, errmsg); + }, err => erregex.test(err.message), errmsg); val *= 0x100; } }