-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
import-in-the-middle
causes exception when creating ERR_MODULE_NOT_FOUND
message
#52987
Comments
Thanks for the issue, if you want to submit a patch, feel free to do so, if not, I'm sure a member of the team will be happy to assist |
@nodejs/loaders correct me if I'm wrong, but wouldn't this behavior also cause errors in the experimental HTTP import system? |
This seems like expected behavior to me. It can't create a URL with that parent. It can't determine that the module doesn't exist if it can't first figure out what URL to try to retrieve. |
Ack, didn't mean to add that label, I was looking to see if we had a "bug" label and I must've misclicked it |
Node is already correctly determining that the file does or does not exist. As described above in the original issue, the error we're encountering actually occurs when Node tries to construct the I agree that the situation that |
Even so, IMO a more descriptive error may be helpful, rather than the one thrown by the conversion utility
|
It has already determined that the module doesn't exist, it's just trying to construct the error message when it throws. I can't see how this is expected behaviour. the code assumes If Just be aware that enforcing this in resolve will break |
And if we did, what error would be thrown? Probably |
Throwing earlier would ensure consistent behavior. Right now, everything happily works with a |
Is
The current error doesn't even tell you which parameter was the wrong scheme. It's totally useless in terms of helping you fix the issue. Because there's no way to debug loader hooks, its difficult to track down. There's a huge difference in terms of DX between an unintentional exception and one designed to guide users of an API. The entire node codebase is full of places where guiding users in this way has been prioritised over just letting random exceptions happen anywhere. |
What do you mean? Resolving a specifier where the URL exists, regardless of
Sure, this could be improved by having the error message specifically refer to
It is definitely challenging to debug code that’s not on the main thread, but it’s not impossible. |
This is exactly what I mean, yes. You can try it for yourself with the example in the original issue; replace
I think there's some confusion here. Again, the error that is currently thrown is not thrown because Node couldn't "look for something on disk". Node does look for the file, determines it does not exist, and is in the process of constructing an node/lib/internal/modules/esm/resolve.js Lines 264 to 265 in 87b87a8
|
Throwing in To fix this issue, it simply needs to not attempt converting |
This isn’t really relevant. If we have a bug, and/or if they have a bug, then it needs to be fixed. The question is what the intended behavior of |
The documentation on https://nodejs.org/api/module.html#resolvespecifier-context-nextresolve doesn't say too much about
I could interpret this to mean that @timfish my hope is that you/we could pursue a fix to |
It's highly relevant. @wesleytodd recently mentioned on Twitter that over the years Node has gone out of their way not to break the ecosystem where possible. The documentation is ambiguous at best. Node has accepted these After this amount of time the "intended behaviour" is irrelevant and the usage in the ecosystem trumps that. It's far less painful to update the docs to reflect the current usage rather than break longstanding packages because the intended behaviour wasn't documented fully in the first place. |
I am not completely sure which topic is referenced here (probably a sign I need to stop checking twitter so much), but I think generally this references how CITGM is in place to help catch ecosystem breaking changes. That said, I am not sure the same goals apply between changing I don't know enough to make a call, and don't have the time availability to come up to speed on this at the moment. Sorry I cannot be more help. |
I opened a PR to fix this in |
This PR fixes the issue that's been described at length in the following issues: - getsentry/sentry-javascript#12011 - nodejs/node#52987 To summarize, `import-in-the-middle` can cause problems in the following situation: - A Node core module (`node:*`) is imported - Another loader is added before `import-in-the-middle` - That loader tries to resolve files that don't exist on disk In practice, this occurs when using `import-in-the-middle` with code that's being executed with [`tsx`](https://github.com/privatenumber/tsx). `tsx` will try to resolve `.js` files by also looking for the same file path but with a `.ts` extension. In many cases, including the synthetic code that `import-in-the-middle` generates to import `lib/register.js`, such a corresponding `.ts` file does not exist. The actual error arises from Node, which assumes that `parentURL` will always be a `file://` URL when constructing an `ERR_MODULE_NOT_FOUND` error; see the linked issue above. In the above scenario, the `.ts` file that is being resolved does not exist, so such an error is created, and `parentURL === 'node:*'`, so the failing case is triggered. It seems like Node is receptive to changing that behavior, but in the meantime, I was hoping to land this patch so that one doesn't have to wait for and upgrade to a new version of Node. The fix works by short-circuiting the resolution of `lib/register.js` so that the other loader (that tries to resolve non-existent paths) is never tried.
Version
v22.1.0
Platform
All
Subsystem
module
What steps will reproduce the bug?
This was triggered by a combination of
import-in-the-middle
andtsx
, but below is a minimal reproduction without either of those.import-in-the-middle
setsparentURL
to node build-ins (node:*
).tsx
tries to resolve files that do not existThe
hook.mjs
index.mjs
Which gives the following error:
This is caused by this code where
base
isnode:util
:node/lib/internal/modules/esm/resolve.js
Lines 264 to 265 in 87b87a8
How often does it reproduce? Is there a required condition?
Every time
What is the expected behavior? Why is that the expected behavior?
This should throw a valid
ERR_MODULE_NOT_FOUND
errorWhat do you see instead?
It's throwing while creating the message
Additional information
This was made incredibly difficult to debug because you can't debug loader hooks!
Credit to @nwalters512 for the back and forth debugging with me!
The text was updated successfully, but these errors were encountered: