Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/daily-wpt-fyi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
# install a version and checkout
- name: Get latest nightly
if: matrix.node-version == 'latest-nightly'
run: echo "NIGHTLY=$(curl -s https://nodejs.org/download/nightly/index.json | jq -r '[.[] | select(.files[] | contains("linux-x64"))][0].version')" >> $GITHUB_ENV
run: echo "NIGHTLY=$(curl -s https://nodejs.org/download/nightly/index.json | jq -r '[.[] | select(.files[] | contains("linux-arm64"))][0].version')" >> $GITHUB_ENV
- name: Install Node.js
id: setup-node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
Expand Down
10 changes: 5 additions & 5 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,11 @@ platforms. This is true regardless of entries in the table below.

Depending on the host platform, the selection of toolchains may vary.

| Operating System | Compiler Versions |
| ---------------- | ------------------------------------------------------------------------- |
| Linux | GCC >= 12.2 or Clang >= 19.1 |
| Windows | Visual Studio 2022 or 2026 with the Windows 10 or 11 SDK on a 64-bit host |
| macOS | Xcode >= 16.4 (Apple LLVM >= 19) |
| Operating System | Compiler Versions |
| ---------------- | ------------------------------------------------------------------- |
| Linux | GCC >= 12.2 or Clang >= 19.1 |
| Windows | Visual Studio 2022 or 2026 with the Windows 11 SDK on a 64-bit host |
| macOS | Xcode >= 16.4 (Apple LLVM >= 19) |

### Official binary platforms and toolchains

Expand Down
12 changes: 2 additions & 10 deletions doc/api/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,7 @@ it('should do the thing', { expectFailure: 'feature not implemented' }, () => {
});
```

If the value of `expectFailure` is a
[<RegExp>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) |
[<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) |
[<Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) |
[<Error>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error),
If the value of `expectFailure` is a {RegExp|Function|Object|Error}
the tests will pass only if they throw a matching value.
See [`assert.throws`][] for how each value type is handled.

Expand Down Expand Up @@ -1734,11 +1730,7 @@ changes:
**Default:** `false`.
* `expectFailure` {boolean|string|RegExp|Function|Object|Error} If truthy, the
test is expected to fail. If a non-empty string is provided, that string is displayed
in the test results as the reason why the test is expected to fail. If a
[<RegExp>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp),
[<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function),
[<Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), or
[<Error>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
in the test results as the reason why the test is expected to fail. If a {RegExp|Function|Object|Error}
is provided directly (without wrapping in `{ match: … }`), the test passes
only if the thrown error matches, following the behavior of
[`assert.throws`][]. To provide both a reason and validation, pass an object
Expand Down
8 changes: 6 additions & 2 deletions lib/internal/webstreams/transformstream.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ const {
const assert = require('internal/assert');

const kSkipThrow = Symbol('kSkipThrow');

const getNonWritablePropertyDescriptor = (value) => {
return {
__proto__: null,
Expand Down Expand Up @@ -524,7 +523,12 @@ function transformStreamDefaultControllerError(controller, error) {

async function transformStreamDefaultControllerPerformTransform(controller, chunk) {
try {
return await controller[kState].transformAlgorithm(chunk, controller);
const transformAlgorithm = controller[kState].transformAlgorithm;
if (transformAlgorithm === undefined) {
// Algorithms were cleared by a concurrent cancel/abort/close.
return;
}
return await transformAlgorithm(chunk, controller);
} catch (error) {
transformStreamError(controller[kState].stream, error);
throw error;
Expand Down
51 changes: 51 additions & 0 deletions test/parallel/test-whatwg-transformstream-cancel-write-race.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict';

require('../common');
const { test } = require('node:test');
const assert = require('node:assert');
const { TransformStream } = require('stream/web');
const { setTimeout } = require('timers/promises');

// https://github.com/nodejs/node/issues/62036

test('Late write racing with reader.cancel() should not throw an internal TypeError', async () => {
const stream = new TransformStream({
transform(chunk, controller) {
controller.enqueue(chunk);
},
});

await setTimeout(0);

const reader = stream.readable.getReader();
const writer = stream.writable.getWriter();

// Release backpressure.
const pendingRead = reader.read();

// Simulate client disconnect / shutdown.
const pendingCancel = reader.cancel(new Error('client disconnected'));

// Late write racing with cancel.
const pendingLateWrite = writer.write('late-write');

const [
readResult,
cancelResult,
lateWriteResult,
] = await Promise.allSettled([
pendingRead,
pendingCancel,
pendingLateWrite,
]);

assert.strictEqual(readResult.status, 'fulfilled');
assert.strictEqual(cancelResult.status, 'fulfilled');
if (lateWriteResult.status === 'rejected') {
const err = lateWriteResult.reason;
const isNotAFunction = err instanceof TypeError &&
/transformAlgorithm is not a function/.test(err.message);
assert.ok(!isNotAFunction,
`Internal implementation error leaked: ${err.message}`);
}
});
1 change: 1 addition & 0 deletions tools/actions/lint-release-proposal-commit-list.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Example:
// $ git log upstream/vXX.x...upstream/vX.X.X-proposal \
// --reverse --format='{"prURL":"%(trailers:key=PR-URL,valueonly,separator=)","title":"%s","smallSha":"%h"}' \
// --abbrev=10 \
// | sed 's/,"title":"Revert "\([^"]\+\)""/,"title":"Revert \\"\1\\""/g' \
// | ./lint-release-proposal-commit-list.mjs "path/to/CHANGELOG.md" "$(git rev-parse upstream/vX.X.X-proposal)"

Expand Down
Loading