Skip to content

Commit 00a38f5

Browse files
committed
stream: yield expected Error class on zlib errors
1 parent 05a536e commit 00a38f5

File tree

2 files changed

+30
-23
lines changed

2 files changed

+30
-23
lines changed

lib/internal/webstreams/adapters.js

+29-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
'use strict';
22

33
const {
4+
Boolean,
5+
ObjectEntries,
46
PromisePrototypeThen,
57
PromiseResolve,
68
SafePromiseAll,
79
SafePromisePrototypeFinally,
10+
SafeSet,
811
TypedArrayPrototypeGetBuffer,
9-
TypedArrayPrototypeGetByteOffset,
1012
TypedArrayPrototypeGetByteLength,
13+
TypedArrayPrototypeGetByteOffset,
14+
TypeError,
1115
Uint8Array,
1216
} = primordials;
1317

@@ -82,6 +86,28 @@ const { UV_EOF } = internalBinding('uv');
8286

8387
const encoder = new TextEncoder();
8488

89+
const ZLIB_FAILURES = new SafeSet([
90+
...ObjectEntries(internalBinding('constants').zlib)
91+
.map(({ 0: code, 1: value }) => (value < 0 ? code : null)).filter(Boolean),
92+
'Z_NEED_DICT',
93+
]);
94+
95+
function handleKnownInternalErrors(cause) {
96+
switch (true) {
97+
case cause?.code === 'ERR_STREAM_PREMATURE_CLOSE': {
98+
return new AbortError(undefined, { cause });
99+
}
100+
case ZLIB_FAILURES.has(cause?.code): {
101+
// eslint-disable-next-line no-restricted-syntax
102+
const error = new TypeError(undefined, { cause });
103+
error.code = cause.code;
104+
return error;
105+
}
106+
default:
107+
return cause;
108+
}
109+
}
110+
85111
/**
86112
* @typedef {import('../../stream').Writable} Writable
87113
* @typedef {import('../../stream').Readable} Readable
@@ -137,10 +163,7 @@ function newWritableStreamFromStreamWritable(streamWritable) {
137163
}
138164

139165
const cleanup = finished(streamWritable, (error) => {
140-
if (error?.code === 'ERR_STREAM_PREMATURE_CLOSE') {
141-
const err = new AbortError(undefined, { cause: error });
142-
error = err;
143-
}
166+
error = handleKnownInternalErrors(error);
144167

145168
cleanup();
146169
// This is a protection against non-standard, legacy streams
@@ -440,10 +463,7 @@ function newReadableStreamFromStreamReadable(streamReadable, options = kEmptyObj
440463
streamReadable.pause();
441464

442465
const cleanup = finished(streamReadable, (error) => {
443-
if (error?.code === 'ERR_STREAM_PREMATURE_CLOSE') {
444-
const err = new AbortError(undefined, { cause: error });
445-
error = err;
446-
}
466+
error = handleKnownInternalErrors(error);
447467

448468
cleanup();
449469
// This is a protection against non-standard, legacy streams

test/wpt/status/compression.json

+1-14
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,8 @@
1414
"decompression-corrupt-input.tentative.any.js": {
1515
"fail": {
1616
"expected": [
17-
"truncating the input for 'deflate' should give an error",
1817
"trailing junk for 'deflate' should give an error",
19-
"format 'deflate' field CMF should be error for 0",
20-
"format 'deflate' field FLG should be error for 157",
21-
"format 'deflate' field DATA should be error for 5",
22-
"format 'deflate' field ADLER should be error for 255",
23-
"truncating the input for 'gzip' should give an error",
24-
"trailing junk for 'gzip' should give an error",
25-
"format 'gzip' field ID should be error for 255",
26-
"format 'gzip' field CM should be error for 0",
27-
"format 'gzip' field FLG should be error for 2",
28-
"format 'gzip' field DATA should be error for 3",
29-
"format 'gzip' field CRC should be error for 0",
30-
"format 'gzip' field ISIZE should be error for 1",
31-
"the deflate input compressed with dictionary should give an error"
18+
"trailing junk for 'gzip' should give an error"
3219
]
3320
}
3421
},

0 commit comments

Comments
 (0)