Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 7 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,13 @@ by the `node:assert` module.
An attempt was made to register something that is not a function as an
`AsyncHooks` callback.

<a id="ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED"></a>

### `ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED`

An operation related to module loading is customized by an asynchronous loader
hook that never settled the promise before the loader thread exits.

<a id="ERR_ASYNC_TYPE"></a>

### `ERR_ASYNC_TYPE`
Expand Down
2 changes: 2 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,8 @@ E('ERR_AMBIGUOUS_ARGUMENT', 'The "%s" argument is ambiguous. %s', TypeError);
E('ERR_ARG_NOT_ITERABLE', '%s must be iterable', TypeError);
E('ERR_ASSERTION', '%s', Error);
E('ERR_ASYNC_CALLBACK', '%s must be a function', TypeError);
E('ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED',
'Async loader request never settled', Error);
E('ERR_ASYNC_TYPE', 'Invalid name for async "type": %s', TypeError);
E('ERR_BROTLI_INVALID_PARAM', '%s is not a valid Brotli parameter', RangeError);
E('ERR_BUFFER_OUT_OF_BOUNDS',
Expand Down
28 changes: 17 additions & 11 deletions lib/internal/modules/esm/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,15 @@ const {
} = globalThis;

const {
ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED,
ERR_INTERNAL_ASSERTION,
ERR_INVALID_ARG_TYPE,
ERR_INVALID_ARG_VALUE,
ERR_INVALID_RETURN_PROPERTY_VALUE,
ERR_INVALID_RETURN_VALUE,
ERR_LOADER_CHAIN_INCOMPLETE,
ERR_METHOD_NOT_IMPLEMENTED,
ERR_WORKER_UNSERIALIZABLE_ERROR,
} = require('internal/errors').codes;
const { exitCodes: { kUnsettledTopLevelAwait } } = internalBinding('errors');
const { URLParse } = require('internal/url');
const { canParse: URLCanParse } = internalBinding('url');
const { receiveMessageOnPort } = require('worker_threads');
Expand Down Expand Up @@ -117,15 +116,16 @@ function defineImportAssertionAlias(context) {
* via `ModuleLoader.#setAsyncLoaderHooks()`.
* @typedef {object} AsyncLoaderHooks
* @property {boolean} allowImportMetaResolve Whether to allow the use of `import.meta.resolve`.
* @property {boolean} isForAsyncLoaderHookWorker Whether the instance is running on the loader hook worker thread.
* @property {(url: string, context: object, defaultLoad: Function) => Promise<LoadResult>} load
* Calling the asynchronous `load` hook asynchronously.
* @property {(url: string, context: object, defaultLoad: Function) => LoadResult} loadSync
* @property {(url: string, context: object, defaultLoad: Function) => LoadResult} [loadSync]
* Calling the asynchronous `load` hook synchronously.
* @property {(originalSpecifier: string, parentURL: string,
* importAttributes: Record<string, string>) => Promise<ResolveResult>} resolve
* Calling the asynchronous `resolve` hook asynchronously.
* @property {(originalSpecifier: string, parentURL: string,
* importAttributes: Record<string, string>) => ResolveResult} resolveSync
* importAttributes: Record<string, string>) => ResolveResult} [resolveSync]
* Calling the asynchronous `resolve` hook synchronously.
* @property {(specifier: string, parentURL: string) => any} register Register asynchronous loader hooks
* @property {() => void} waitForLoaderHookInitialization Force loading of hooks.
Expand Down Expand Up @@ -169,6 +169,8 @@ class AsyncLoaderHooksOnLoaderHookWorker {

allowImportMetaResolve = false;

isForAsyncLoaderHookWorker = true;
Comment thread
joyeecheung marked this conversation as resolved.

/**
* Import and register custom/user-defined module loader hook(s).
* @param {string} urlOrSpecifier
Expand Down Expand Up @@ -350,10 +352,6 @@ class AsyncLoaderHooksOnLoaderHookWorker {
};
}

resolveSync(_originalSpecifier, _parentURL, _importAttributes) {
throw new ERR_METHOD_NOT_IMPLEMENTED('resolveSync()');
}

/**
* Provide source that is understood by one of Node's translators.
*
Expand Down Expand Up @@ -560,7 +558,10 @@ class AsyncLoaderHookWorker {
debug('wait for signal from worker');
AtomicsWait(this.#lock, WORKER_TO_MAIN_THREAD_NOTIFICATION, 0);
const response = this.#worker.receiveMessageSync();
if (response == null || response.message.status === 'exit') { return; }
if (response == null) { return; }
if (response.message.status === 'exit') {
process.exit(response.message.body);
}

// ! This line catches initialization errors in the worker thread.
this.#unwrapMessage(response);
Expand Down Expand Up @@ -647,10 +648,13 @@ class AsyncLoaderHookWorker {
this.#workerNotificationLastId = AtomicsLoad(this.#lock, WORKER_TO_MAIN_THREAD_NOTIFICATION);

response = this.#worker.receiveMessageSync();
debug('got sync message from worker', { method, args, response });
} while (response == null);
debug('got sync response from worker', { method, args });

if (response.message.status === 'never-settle') {
process.exit(kUnsettledTopLevelAwait);
const error = new ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED();
error.details = { method, args };
throw error;
} else if (response.message.status === 'exit') {
process.exit(response.message.body);
}
Expand Down Expand Up @@ -819,6 +823,8 @@ class AsyncLoaderHooksProxiedToLoaderHookWorker {

allowImportMetaResolve = true;

isForAsyncLoaderHookWorker = false;

/**
* Instantiate a module loader that uses user-provided custom loader hooks.
*/
Expand Down
3 changes: 2 additions & 1 deletion lib/internal/modules/esm/initialize_import_meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ function createImportMetaResolve(defaultParentURL, loader, allowParentURL) {
}

try {
({ url } = loader.resolveSync(specifier, parentURL));
const request = { specifier, __proto__: null };
({ url } = loader.resolveSync(parentURL, request));
return url;
} catch (error) {
switch (error?.code) {
Expand Down
Loading
Loading