Skip to content
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

Abort signal is not respected #25

Closed
2color opened this issue Mar 19, 2024 · 10 comments · Fixed by #26 or #30
Closed

Abort signal is not respected #25

2color opened this issue Mar 19, 2024 · 10 comments · Fixed by #26 or #30
Assignees
Labels
need/author-input Needs input from the original author

Comments

@2color
Copy link
Member

2color commented Mar 19, 2024

When passing an new AbortController().signal to a verifiedFetch request, aborting does not seem to work.

You can see this in action in the reproduction, where if you click to fetch IPNS and right after click Abort Fetch, the controller.abort() call does not cause the promise from the verifiedFetch call to throw an error as you'd expect in Fetch

To make this easier to test, I've added a reproduction:

Reproduction

@2color 2color moved this to 🥞 Todo in IPFS Shipyard Team Mar 19, 2024
@2color 2color added the kind/bug A bug in existing code (including security flaws) label Mar 19, 2024
@SgtPooki
Copy link
Member

This could be why the first request takes so long with ipfs/service-worker-gateway#122

Will investigate further tomorrow

@SgtPooki SgtPooki linked a pull request Mar 21, 2024 that will close this issue
3 tasks
@github-project-automation github-project-automation bot moved this from 🥞 Todo to 🎉 Done in IPFS Shipyard Team Mar 21, 2024
@SgtPooki
Copy link
Member

verified that when updated to 1.3.0, fetchIPNS and then abort result in "400" status code: https://codesandbox.io/p/sandbox/heali-verified-fetch-example-m5zmfd?file=%2Findex.html

sometimes the buttons don't seem to trigger anything, but I believe this is resolved 👍

@SgtPooki SgtPooki self-assigned this Mar 21, 2024
@2color
Copy link
Member Author

2color commented Mar 22, 2024

verifiedFetch should throw an error, i.e., not resolve the Promise, if the request is aborted to be consistent with Fetch

https://developer.mozilla.org/en-US/docs/Web/API/AbortController

Note: When abort() is called, the fetch() promise rejects with a DOMException named AbortError.

@2color 2color reopened this Mar 22, 2024
@2color 2color moved this from 🎉 Done to 🏃‍♀️ In Progress in IPFS Shipyard Team Mar 22, 2024
@SgtPooki
Copy link
Member

we can't actually throw a legit AbortError, so i'll update to throw @libp2p/interface's AbortError

some context in: nodejs/node#40692

@SgtPooki SgtPooki linked a pull request Mar 22, 2024 that will close this issue
3 tasks
@github-project-automation github-project-automation bot moved this from 🏃‍♀️ In Progress to 🎉 Done in IPFS Shipyard Team Mar 22, 2024
@2color
Copy link
Member Author

2color commented Mar 25, 2024

Thanks @SgtPooki!

The only thing that's a bit burdensome about the custom AbortError is that it doesn't have the name property set to AbortError.

https://github.com/libp2p/js-libp2p/blob/d12cdce8e58012a1f01cb06c4fcc7adec1c1818f/packages/interface/src/errors.ts#L6-L19

So checking for this error either requires importing the error type:

import {AbortError} from '@libp2p/interface'
...
} catch (err) {
      if(err instanceof AbortError) {
        console.log('all good 🎉 no need to set error since the user aborted.')
}
...

I tried checking the custom code or type properties, which are defined on the AbortError type, but both of these result in a TypeScript type errors

Screenshot 2024-03-25 at 2 12 49 pm Screenshot 2024-03-25 at 2 19 57 pm

Suggestion

Given this, I think it would be useful to follow the same convention as built-in error objects and set the name to the class name of the error. This would allow this kind of check without importing custom error types while keeping the TS compiler happy:

} catch (err) {
      if(err instanceof Error && err.name === 'AbortError') {
        console.log('all good 🎉 no need to set error since the user aborted.')
}
...

WDYT, @SgtPooki ?

@SgtPooki
Copy link
Member

@2color that sounds good.. I think we should add a .name property to errors in libp2p.

However, I think that libp2p checks .code even though nodejs/node#40692 suggests checking the .name property

AbortError has a .code of ABORT_ERR that we can check today.

see https://codepen.io/SgtPooki/pen/bGJRoeB?editors=1011

@2color
Copy link
Member Author

2color commented Mar 25, 2024

AbortError has a .code of ABORT_ERR that we can check today.

The problem with .code is that I haven't found a way to check it using typescript without explicitly importing the type from js-libp2p/interface or setting the e: any in the catch clause.

@achingbrain
Copy link
Member

achingbrain commented Mar 27, 2024

Normally you'd just do something like this:

} catch (err: any) {
      if (err.code === 'ABORT_ERR') {
        console.log('all good 🎉 no need to set error since the user aborted.')
}

The any is 🤮 but this is JavaScript not Java, there's nothing to stop non-Error instances being thrown (linting, yes, but it could be thrown from code you don't control) so it's a free-for-all anyway.

achingbrain pushed a commit to libp2p/js-libp2p that referenced this issue Mar 28, 2024
As discussed in ipfs/helia-verified-fetch#25 (comment), this PR adds the name property to the AbortError type. 

This has a couple of benefits:
- Sticks the common convention for Error types (all built in Error types have the name property set to the class name)
- Allows checking the error type at runtime in a TS codebase without importing the type

Co-authored-by: Daniel N <[email protected]>
@SgtPooki
Copy link
Member

AFAIK, all we should need to do here now is update to latest helia + libp2p and we should be good to go, right?

@SgtPooki
Copy link
Member

SgtPooki commented Apr 3, 2024

@helia/verified-fetch is respecting abort signals now.. I think we can close this.

@SgtPooki SgtPooki added need/author-input Needs input from the original author and removed kind/bug A bug in existing code (including security flaws) labels Apr 3, 2024
@2color 2color closed this as completed Apr 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
need/author-input Needs input from the original author
Projects
No open projects
Status: 🎉 Done
3 participants