Skip to content

Commit

Permalink
zlib: migrate to internal/errors
Browse files Browse the repository at this point in the history
PR-URL: nodejs/node#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 authored and addaleax committed Oct 4, 2017
1 parent fd82844 commit 6b2143b
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 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`.

<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>
### 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
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>
### 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.

<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
[`subprocess.kill()`]: child_process.html#child_process_subprocess_kill_signal
[`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 Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
const kCode = Symbol('code');
const messages = new Map();

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

// Lazily loaded
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_TYPE', (s) => `Invalid name for async "type": ${s}`);
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_CONSOLE_WRITABLE_STREAM',
'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');
E('ERR_INDEX_OUT_OF_RANGE', 'Index out of range');
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',
(name, len, actual) => {
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) => {
return `The value of "${start}" must be ${end}. Received "${value}"`;
});
E('ERR_ZLIB_BINDING_CLOSED', 'zlib binding closed');

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

'use strict';

const Buffer = require('buffer').Buffer;
const errors = require('internal/errors');
const Transform = require('_stream_transform');
const { _extend } = require('util');
const { isArrayBufferView } = require('internal/util/types');
const binding = process.binding('zlib');
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 {
Buffer,
kMaxLength
} = require('buffer');

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

var error = new Error(message);
const error = new Error(message);
error.errno = errno;
error.code = codes[errno];
self.emit('error', error);
Expand Down Expand Up @@ -163,15 +165,17 @@ function Zlib(opts, mode) {
chunkSize = opts.chunkSize;
if (chunkSize !== undefined && chunkSize === 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 {
chunkSize = Z_DEFAULT_CHUNK;
}

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

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

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) {
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 &&
(strategy < Z_DEFAULT_STRATEGY || strategy > Z_FIXED ||
!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) {
Expand Down Expand Up @@ -455,7 +467,7 @@ function processChunkSync(self, chunk, flushFlag) {

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

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

handle.buffer = chunk;
handle.cb = cb;
Expand Down
17 changes: 17 additions & 0 deletions test/parallel/test-internal-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,20 @@ assert.strictEqual(
assert.strictEqual(
errors.message('ERR_INVALID_ASYNC_ID', ['asyncId', 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 6b2143b

Please sign in to comment.