fs: add signal option to fs.stat()

PR-URL: https://github.com/nodejs/node/pull/57775
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jason Zhang <xzha4350@gmail.com>
Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
This commit is contained in:
Mert Can Altin authored and GitHub committed 2026-04-09 04:24:41 +00:00
1 parent 586403f0c4
commit 7b6a07220f
3 files changed
+49 -5

No files matched your search

+6 -4
View File
@@ -778,15 +778,17 @@ Read from a file and write to an array of {ArrayBufferView}s
<!-- YAML
added: v10.0.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/57775
description: Now accepts an additional `signal` property to allow aborting the operation.
- version: v10.5.0
pr-url: https://github.com/nodejs/node/pull/20220
description: Accepts an additional `options` object to specify whether
the numeric values returned should be bigint.
description: Accepts an additional `options` object to specify whether the numeric values returned should be bigint.
-->
* `options` {Object}
* `bigint` {boolean} Whether the numeric values in the returned
{fs.Stats} object should be `bigint`. **Default:** `false`.
* `bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.
* `signal` {AbortSignal} An AbortSignal to cancel the operation. **Default:** `undefined`.
* Returns: {Promise} Fulfills with an {fs.Stats} for the file.
#### `filehandle.sync()`
+9 -1
View File
@@ -1615,7 +1615,7 @@ function lstat(path, options = { bigint: false }, callback) {
/**
* Asynchronously gets the stats of a file.
* @param {string | Buffer | URL} path
* @param {{ bigint?: boolean; }} [options]
* @param {{ bigint?: boolean, signal?: AbortSignal }} [options]
* @param {(
* err?: Error,
* stats?: Stats
@@ -1626,8 +1626,16 @@ function stat(path, options = { bigint: false, throwIfNoEntry: true }, callback)
if (typeof options === 'function') {
callback = options;
options = kEmptyObject;
} else if (options === null || typeof options !== 'object') {
options = kEmptyObject;
} else {
options = getOptions(options, { bigint: false });
}
callback = makeStatsCallback(callback);
path = getValidatedPath(path);
if (checkAborted(options.signal, callback)) return;
const req = new FSReqCallback(options.bigint);
req.oncomplete = callback;
+34
View File
@@ -0,0 +1,34 @@
'use strict';
require('../common');
const test = require('node:test');
const assert = require('node:assert');
const fs = require('node:fs');
const tmpdir = require('../common/tmpdir');
test('fs.stat should throw AbortError when called with an already aborted AbortSignal', async () => {
// This test verifies that fs.stat immediately throws an AbortError if the provided AbortSignal
// has already been canceled. This approach is used because trying to abort an fs.stat call in flight
// is unreliable given that file system operations tend to complete very quickly on many platforms.
tmpdir.refresh();
const filePath = tmpdir.resolve('temp.txt');
fs.writeFileSync(filePath, 'Test');
// Create an already aborted AbortSignal.
const signal = AbortSignal.abort();
const { promise, resolve, reject } = Promise.withResolvers();
fs.stat(filePath, { signal }, (err, stats) => {
if (err) {
return reject(err);
}
resolve(stats);
});
// Assert that the promise is rejected with an AbortError.
await assert.rejects(promise, { name: 'AbortError' });
fs.unlinkSync(filePath);
tmpdir.refresh();
});