diff --git a/doc/api/fs.md b/doc/api/fs.md index 2232528e47c980..ac936bbad1263e 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -6773,8 +6773,8 @@ changes: description: No longer experimental. --> -Calls `dir.close()` and returns a promise that fulfills when the -dir is closed. +Calls `dir.close()` if the directory handle is open, and returns a promise that +fulfills when disposal is complete. #### `dir[Symbol.dispose]()` @@ -6786,7 +6786,8 @@ changes: description: No longer experimental. --> -Calls `dir.closeSync()` and returns `undefined`. +Calls `dir.closeSync()` if the directory handle is open, and returns +`undefined`. ### Class: `fs.Dirent` diff --git a/lib/internal/fs/dir.js b/lib/internal/fs/dir.js index 349d0fa2dbb21e..f7b89b1fa8dba2 100644 --- a/lib/internal/fs/dir.js +++ b/lib/internal/fs/dir.js @@ -24,7 +24,6 @@ const { const { FSReqCallback } = binding; const { - assignFunctionName, promisify, } = require('internal/util'); const { @@ -296,31 +295,24 @@ class Dir { await this.#closePromisified(); } } + + [SymbolDispose]() { + if (this.#closed) return; + this.closeSync(); + } + + async [SymbolAsyncDispose]() { + if (this.#closed) return; + await this.#closePromisified(); + } } -const nonEnumerableDescriptor = { - enumerable: false, - writable: true, - configurable: true, -}; ObjectDefineProperties(Dir.prototype, { - [SymbolDispose]: { - __proto__: null, - ...nonEnumerableDescriptor, - value: assignFunctionName(SymbolDispose, function() { - this.closeSync(); - }), - }, - [SymbolAsyncDispose]: { - __proto__: null, - ...nonEnumerableDescriptor, - value: assignFunctionName(SymbolAsyncDispose, function() { - this.close(); - }), - }, [SymbolAsyncIterator]: { __proto__: null, - ...nonEnumerableDescriptor, + enumerable: false, + writable: true, + configurable: true, value: Dir.prototype.entries, }, }); diff --git a/test/parallel/test-fs-promises-file-handle-dispose.js b/test/parallel/test-fs-promises-file-handle-dispose.js index 2d58d1ed37e4d7..3e7ef3066a7c86 100644 --- a/test/parallel/test-fs-promises-file-handle-dispose.js +++ b/test/parallel/test-fs-promises-file-handle-dispose.js @@ -11,10 +11,14 @@ async function explicitCall() { const dh = await fs.opendir(__dirname); await dh[Symbol.asyncDispose](); + // Repeat invocations should not reject + await dh[Symbol.asyncDispose](); await assert.rejects(dh.read(), { code: 'ERR_DIR_CLOSED' }); const dhSync = opendirSync(__dirname); dhSync[Symbol.dispose](); + // Repeat invocations should not throw + dhSync[Symbol.dispose](); assert.throws(() => dhSync.readSync(), { code: 'ERR_DIR_CLOSED' }); }