diff --git a/lib/internal/modules/esm/hooks.js b/lib/internal/modules/esm/hooks.js index 5f5e17f60fe05a..e30ef7e895d1f2 100644 --- a/lib/internal/modules/esm/hooks.js +++ b/lib/internal/modules/esm/hooks.js @@ -34,6 +34,7 @@ const { ERR_WORKER_UNSERIALIZABLE_ERROR, } = require('internal/errors').codes; const { URL } = require('internal/url'); +const { canParse: urlCanParse } = internalBinding('url'); const { receiveMessageOnPort } = require('worker_threads'); const { isAnyArrayBuffer, @@ -270,10 +271,8 @@ class Hooks { // Avoid expensive URL instantiation for known-good URLs if (!this.#validatedUrls.has(url)) { - try { - new URL(url); - this.#validatedUrls.add(url); - } catch { + // No need to convert to string, since the type is already validated + if (!urlCanParse(url)) { throw new ERR_INVALID_RETURN_PROPERTY_VALUE( 'a URL string', hookErrIdentifier, @@ -281,6 +280,8 @@ class Hooks { url, ); } + + this.#validatedUrls.add(url); } if ( @@ -349,16 +350,16 @@ class Hooks { // Avoid expensive URL instantiation for known-good URLs if (!this.#validatedUrls.has(nextUrl)) { - try { - new URL(nextUrl); - this.#validatedUrls.add(nextUrl); - } catch { + // No need to convert to string, since the type is already validated + if (!urlCanParse(nextUrl)) { throw new ERR_INVALID_ARG_VALUE( `${hookErrIdentifier} url`, nextUrl, 'should be a URL string', ); } + + this.#validatedUrls.add(nextUrl); } if (ctx) { validateObject(ctx, `${hookErrIdentifier} context`); } diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 15c0e91df318b4..ed831db7648506 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -39,6 +39,7 @@ const experimentalNetworkImports = getOptionValue('--experimental-network-imports'); const typeFlag = getOptionValue('--input-type'); const { URL, pathToFileURL, fileURLToPath, toPathIfFileURL, isURL } = require('internal/url'); +const { canParse: canParseURL } = internalBinding('url'); const { ERR_INPUT_TYPE_NOT_ALLOWED, ERR_INVALID_ARG_TYPE, @@ -393,14 +394,8 @@ function resolvePackageTargetString( if (!StringPrototypeStartsWith(target, './')) { if (internal && !StringPrototypeStartsWith(target, '../') && !StringPrototypeStartsWith(target, '/')) { - let isURL = false; - try { - new URL(target); - isURL = true; - } catch { - // Continue regardless of error. - } - if (!isURL) { + // No need to convert target to string, since it's already presumed to be + if (!canParseURL(target)) { const exportTarget = pattern ? RegExpPrototypeSymbolReplace(patternRegEx, target, () => subpath) : target + subpath;