Skip to content

Commit

Permalink
zlib: migrate to internal/errors
Browse files Browse the repository at this point in the history
PR-URL: #15618
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
  • Loading branch information
jasnell committed Oct 2, 2017
1 parent 1f8d527 commit 7489141
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 101 deletions.
18 changes: 18 additions & 0 deletions doc/api/errors.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -609,6 +609,12 @@ also able to define their own types when using the public embedder API.


Used when attempting to perform an operation outside the bounds of a `Buffer`. Used when attempting to perform an operation outside the bounds of a `Buffer`.


<a id="ERR_BUFFER_TOO_LARGE"></a>
### ERR_BUFFER_TOO_LARGE

Used when an attempt has been made to create a `Buffer` larger than the
maximum allowed size.

<a id="ERR_CHILD_CLOSED_BEFORE_REPLY"></a> <a id="ERR_CHILD_CLOSED_BEFORE_REPLY"></a>
### ERR_CHILD_CLOSED_BEFORE_REPLY ### ERR_CHILD_CLOSED_BEFORE_REPLY


Expand Down Expand Up @@ -879,6 +885,12 @@ Used when a given index is out of the accepted range (e.g. negative offsets).
Used generically to identify that an argument of the wrong type has been passed Used generically to identify that an argument of the wrong type has been passed
to a Node.js API. to a Node.js API.


<a id="ERR_INVALID_ARG_VALUE"></a>
### ERR_INVALID_ARG_VALUE

Used generically to identify that an invalid or unsupported value has been
passed for a given argument.

<a id="ERR_INVALID_ARRAY_LENGTH"></a> <a id="ERR_INVALID_ARRAY_LENGTH"></a>
### ERR_INVALID_ARRAY_LENGTH ### ERR_INVALID_ARRAY_LENGTH


Expand Down Expand Up @@ -1277,6 +1289,12 @@ entry types were found.


Used when a given value is out of the accepted range. Used when a given value is out of the accepted range.


<a id="ERR_ZLIB_BINDING_CLOSED"></a>
### ERR_ZLIB_BINDING_CLOSED

Used when an attempt is made to use a `zlib` object after it has already been
closed.

[`ERR_INVALID_ARG_TYPE`]: #ERR_INVALID_ARG_TYPE [`ERR_INVALID_ARG_TYPE`]: #ERR_INVALID_ARG_TYPE
[`subprocess.kill()`]: child_process.html#child_process_subprocess_kill_signal [`subprocess.kill()`]: child_process.html#child_process_subprocess_kill_signal
[`subprocess.send()`]: child_process.html#child_process_subprocess_send_message_sendhandle_options_callback [`subprocess.send()`]: child_process.html#child_process_subprocess_send_message_sendhandle_options_callback
Expand Down
11 changes: 11 additions & 0 deletions lib/internal/errors.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
const kCode = Symbol('code'); const kCode = Symbol('code');
const messages = new Map(); const messages = new Map();


const {
kMaxLength
} = process.binding('buffer');

// Lazily loaded // Lazily loaded
var util = null; var util = null;


Expand Down Expand Up @@ -121,6 +125,8 @@ E('ERR_ASSERTION', '%s');
E('ERR_ASYNC_CALLBACK', (name) => `${name} must be a function`); E('ERR_ASYNC_CALLBACK', (name) => `${name} must be a function`);
E('ERR_ASYNC_TYPE', (s) => `Invalid name for async "type": ${s}`); E('ERR_ASYNC_TYPE', (s) => `Invalid name for async "type": ${s}`);
E('ERR_BUFFER_OUT_OF_BOUNDS', bufferOutOfBounds); E('ERR_BUFFER_OUT_OF_BOUNDS', bufferOutOfBounds);
E('ERR_BUFFER_TOO_LARGE',
`Cannot create a Buffer larger than 0x${kMaxLength.toString(16)} bytes`);
E('ERR_CHILD_CLOSED_BEFORE_REPLY', 'Child closed before reply received'); E('ERR_CHILD_CLOSED_BEFORE_REPLY', 'Child closed before reply received');
E('ERR_CONSOLE_WRITABLE_STREAM', E('ERR_CONSOLE_WRITABLE_STREAM',
'Console expects a writable stream instance for %s'); 'Console expects a writable stream instance for %s');
Expand Down Expand Up @@ -206,6 +212,10 @@ E('ERR_HTTP_TRAILER_INVALID',
'Trailers are invalid with this transfer encoding'); 'Trailers are invalid with this transfer encoding');
E('ERR_INDEX_OUT_OF_RANGE', 'Index out of range'); E('ERR_INDEX_OUT_OF_RANGE', 'Index out of range');
E('ERR_INVALID_ARG_TYPE', invalidArgType); E('ERR_INVALID_ARG_TYPE', invalidArgType);
E('ERR_INVALID_ARG_VALUE',
(name, value) => {
return `The value "${String(value)}" is invalid for argument "${name}"`;
});
E('ERR_INVALID_ARRAY_LENGTH', E('ERR_INVALID_ARRAY_LENGTH',
(name, len, actual) => { (name, len, actual) => {
internalAssert(typeof actual === 'number', 'actual must be a number'); internalAssert(typeof actual === 'number', 'actual must be a number');
Expand Down Expand Up @@ -303,6 +313,7 @@ E('ERR_VALID_PERFORMANCE_ENTRY_TYPE',
E('ERR_VALUE_OUT_OF_RANGE', (start, end, value) => { E('ERR_VALUE_OUT_OF_RANGE', (start, end, value) => {
return `The value of "${start}" must be ${end}. Received "${value}"`; return `The value of "${start}" must be ${end}. Received "${value}"`;
}); });
E('ERR_ZLIB_BINDING_CLOSED', 'zlib binding closed');


function invalidArgType(name, expected, actual) { function invalidArgType(name, expected, actual) {
internalAssert(name, 'name is required'); internalAssert(name, 'name is required');
Expand Down
54 changes: 33 additions & 21 deletions lib/zlib.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@


'use strict'; 'use strict';


const Buffer = require('buffer').Buffer; const errors = require('internal/errors');
const Transform = require('_stream_transform'); const Transform = require('_stream_transform');
const { _extend } = require('util'); const { _extend } = require('util');
const { isArrayBufferView } = require('internal/util/types'); const { isArrayBufferView } = require('internal/util/types');
const binding = process.binding('zlib'); const binding = process.binding('zlib');
const assert = require('assert').ok; const assert = require('assert').ok;
const kMaxLength = require('buffer').kMaxLength; const {
const kRangeErrorMessage = 'Cannot create final Buffer. It would be larger ' + Buffer,
`than 0x${kMaxLength.toString(16)} bytes`; kMaxLength
} = require('buffer');


const constants = process.binding('constants').zlib; const constants = process.binding('constants').zlib;
const { const {
Expand Down Expand Up @@ -93,7 +94,7 @@ function zlibBufferOnEnd() {
var buf; var buf;
var err; var err;
if (this.nread >= kMaxLength) { if (this.nread >= kMaxLength) {
err = new RangeError(kRangeErrorMessage); err = new errors.RangeError('ERR_BUFFER_TOO_LARGE');
} else { } else {
var bufs = this.buffers; var bufs = this.buffers;
buf = (bufs.length === 1 ? bufs[0] : Buffer.concat(bufs, this.nread)); buf = (bufs.length === 1 ? bufs[0] : Buffer.concat(bufs, this.nread));
Expand All @@ -111,8 +112,9 @@ function zlibBufferSync(engine, buffer) {
if (typeof buffer === 'string') { if (typeof buffer === 'string') {
buffer = Buffer.from(buffer); buffer = Buffer.from(buffer);
} else if (!isArrayBufferView(buffer)) { } else if (!isArrayBufferView(buffer)) {
throw new TypeError('"buffer" argument must be a string, Buffer, ' + throw new errors.TypeError('ERR_INVALID_ARG_TYPE',
'TypedArray, or DataView'); 'buffer',
['string', 'Buffer', 'TypedArray', 'DataView']);
} }
buffer = processChunkSync(engine, buffer, engine._finishFlushFlag); buffer = processChunkSync(engine, buffer, engine._finishFlushFlag);
if (engine._info) if (engine._info)
Expand All @@ -128,7 +130,7 @@ function zlibOnError(message, errno) {
_close(self); _close(self);
self._hadError = true; self._hadError = true;


var error = new Error(message); const error = new Error(message);
error.errno = errno; error.errno = errno;
error.code = codes[errno]; error.code = codes[errno];
self.emit('error', error); self.emit('error', error);
Expand Down Expand Up @@ -163,15 +165,17 @@ function Zlib(opts, mode) {
chunkSize = opts.chunkSize; chunkSize = opts.chunkSize;
if (chunkSize !== undefined && chunkSize === chunkSize) { if (chunkSize !== undefined && chunkSize === chunkSize) {
if (chunkSize < Z_MIN_CHUNK || !Number.isFinite(chunkSize)) if (chunkSize < Z_MIN_CHUNK || !Number.isFinite(chunkSize))
throw new RangeError('Invalid chunk size: ' + chunkSize); throw new errors.RangeError('ERR_INVALID_OPT_VALUE',
'chunkSize',
chunkSize);
} else { } else {
chunkSize = Z_DEFAULT_CHUNK; chunkSize = Z_DEFAULT_CHUNK;
} }


flush = opts.flush; flush = opts.flush;
if (flush !== undefined && flush === flush) { if (flush !== undefined && flush === flush) {
if (flush < Z_NO_FLUSH || flush > Z_BLOCK || !Number.isFinite(flush)) if (flush < Z_NO_FLUSH || flush > Z_BLOCK || !Number.isFinite(flush))
throw new RangeError('Invalid flush flag: ' + flush); throw new errors.RangeError('ERR_INVALID_OPT_VALUE', 'flush', flush);
} else { } else {
flush = Z_NO_FLUSH; flush = Z_NO_FLUSH;
} }
Expand All @@ -180,7 +184,9 @@ function Zlib(opts, mode) {
if (finishFlush !== undefined && finishFlush === finishFlush) { if (finishFlush !== undefined && finishFlush === finishFlush) {
if (finishFlush < Z_NO_FLUSH || finishFlush > Z_BLOCK || if (finishFlush < Z_NO_FLUSH || finishFlush > Z_BLOCK ||
!Number.isFinite(finishFlush)) { !Number.isFinite(finishFlush)) {
throw new RangeError('Invalid flush flag: ' + finishFlush); throw new errors.RangeError('ERR_INVALID_OPT_VALUE',
'finishFlush',
finishFlush);
} }
} else { } else {
finishFlush = Z_FINISH; finishFlush = Z_FINISH;
Expand All @@ -190,7 +196,9 @@ function Zlib(opts, mode) {
if (windowBits !== undefined && windowBits === windowBits) { if (windowBits !== undefined && windowBits === windowBits) {
if (windowBits < Z_MIN_WINDOWBITS || windowBits > Z_MAX_WINDOWBITS || if (windowBits < Z_MIN_WINDOWBITS || windowBits > Z_MAX_WINDOWBITS ||
!Number.isFinite(windowBits)) { !Number.isFinite(windowBits)) {
throw new RangeError('Invalid windowBits: ' + windowBits); throw new errors.RangeError('ERR_INVALID_OPT_VALUE',
'windowBits',
windowBits);
} }
} else { } else {
windowBits = Z_DEFAULT_WINDOWBITS; windowBits = Z_DEFAULT_WINDOWBITS;
Expand All @@ -200,7 +208,8 @@ function Zlib(opts, mode) {
if (level !== undefined && level === level) { if (level !== undefined && level === level) {
if (level < Z_MIN_LEVEL || level > Z_MAX_LEVEL || if (level < Z_MIN_LEVEL || level > Z_MAX_LEVEL ||
!Number.isFinite(level)) { !Number.isFinite(level)) {
throw new RangeError('Invalid compression level: ' + level); throw new errors.RangeError('ERR_INVALID_OPT_VALUE',
'level', level);
} }
} else { } else {
level = Z_DEFAULT_COMPRESSION; level = Z_DEFAULT_COMPRESSION;
Expand All @@ -210,7 +219,8 @@ function Zlib(opts, mode) {
if (memLevel !== undefined && memLevel === memLevel) { if (memLevel !== undefined && memLevel === memLevel) {
if (memLevel < Z_MIN_MEMLEVEL || memLevel > Z_MAX_MEMLEVEL || if (memLevel < Z_MIN_MEMLEVEL || memLevel > Z_MAX_MEMLEVEL ||
!Number.isFinite(memLevel)) { !Number.isFinite(memLevel)) {
throw new RangeError('Invalid memLevel: ' + memLevel); throw new errors.RangeError('ERR_INVALID_OPT_VALUE',
'memLevel', memLevel);
} }
} else { } else {
memLevel = Z_DEFAULT_MEMLEVEL; memLevel = Z_DEFAULT_MEMLEVEL;
Expand All @@ -220,16 +230,18 @@ function Zlib(opts, mode) {
if (strategy !== undefined && strategy === strategy) { if (strategy !== undefined && strategy === strategy) {
if (strategy < Z_DEFAULT_STRATEGY || strategy > Z_FIXED || if (strategy < Z_DEFAULT_STRATEGY || strategy > Z_FIXED ||
!Number.isFinite(strategy)) { !Number.isFinite(strategy)) {
throw new TypeError('Invalid strategy: ' + strategy); throw new errors.TypeError('ERR_INVALID_OPT_VALUE',
'strategy', strategy);
} }
} else { } else {
strategy = Z_DEFAULT_STRATEGY; strategy = Z_DEFAULT_STRATEGY;
} }


dictionary = opts.dictionary; dictionary = opts.dictionary;
if (dictionary !== undefined && !isArrayBufferView(dictionary)) { if (dictionary !== undefined && !isArrayBufferView(dictionary)) {
throw new TypeError( throw new errors.TypeError('ERR_INVALID_OPT_VALUE',
'Invalid dictionary: it should be a Buffer, TypedArray, or DataView'); 'dictionary',
dictionary);
} }


if (opts.encoding || opts.objectMode || opts.writableObjectMode) { if (opts.encoding || opts.objectMode || opts.writableObjectMode) {
Expand Down Expand Up @@ -273,12 +285,12 @@ Object.defineProperty(Zlib.prototype, '_closed', {


Zlib.prototype.params = function params(level, strategy, callback) { Zlib.prototype.params = function params(level, strategy, callback) {
if (level < Z_MIN_LEVEL || level > Z_MAX_LEVEL) if (level < Z_MIN_LEVEL || level > Z_MAX_LEVEL)
throw new RangeError('Invalid compression level: ' + level); throw new errors.RangeError('ERR_INVALID_ARG_VALUE', 'level', level);


if (strategy !== undefined && if (strategy !== undefined &&
(strategy < Z_DEFAULT_STRATEGY || strategy > Z_FIXED || (strategy < Z_DEFAULT_STRATEGY || strategy > Z_FIXED ||
!Number.isFinite(strategy))) { !Number.isFinite(strategy))) {
throw new TypeError('Invalid strategy: ' + strategy); throw new errors.TypeError('ERR_INVALID_ARG_VALUE', 'strategy', strategy);
} }


if (this._level !== level || this._strategy !== strategy) { if (this._level !== level || this._strategy !== strategy) {
Expand Down Expand Up @@ -455,7 +467,7 @@ function processChunkSync(self, chunk, flushFlag) {


if (nread >= kMaxLength) { if (nread >= kMaxLength) {
_close(self); _close(self);
throw new RangeError(kRangeErrorMessage); throw new errors.RangeError('ERR_BUFFER_TOO_LARGE');
} }


_close(self); _close(self);
Expand All @@ -466,7 +478,7 @@ function processChunkSync(self, chunk, flushFlag) {
function processChunk(self, chunk, flushFlag, cb) { function processChunk(self, chunk, flushFlag, cb) {
var handle = self._handle; var handle = self._handle;
if (!handle) if (!handle)
return cb(new Error('zlib binding closed')); return cb(new errors.Error('ERR_ZLIB_BINDING_CLOSED'));


handle.buffer = chunk; handle.buffer = chunk;
handle.cb = cb; handle.cb = cb;
Expand Down
17 changes: 17 additions & 0 deletions test/parallel/test-internal-errors.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -284,3 +284,20 @@ assert.strictEqual(
assert.strictEqual( assert.strictEqual(
errors.message('ERR_INVALID_ASYNC_ID', ['asyncId', undefined]), errors.message('ERR_INVALID_ASYNC_ID', ['asyncId', undefined]),
'Invalid asyncId value: undefined'); 'Invalid asyncId value: undefined');

{
const { kMaxLength } = process.binding('buffer');
const error = new errors.Error('ERR_BUFFER_TOO_LARGE');
assert.strictEqual(
error.message,
`Cannot create a Buffer larger than 0x${kMaxLength.toString(16)} bytes`
);
}

{
const error = new errors.Error('ERR_INVALID_ARG_VALUE', 'foo', 'bar');
assert.strictEqual(
error.message,
'The value "bar" is invalid for argument "foo"'
);
}
Loading

0 comments on commit 7489141

Please sign in to comment.