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

Fix signal handling for Request objects #613

Merged
merged 4 commits into from
Jul 31, 2024

Conversation

crisshaker
Copy link
Contributor

Currently, ky ignores AbortSignal when it's provided as part of a Request object.

This PR modifies the Ky class to properly extract and respect the AbortSignal from Request objects. It ensures that signals are handled consistently whether they're provided directly in the options or as part of a Request object.

@sindresorhus
Copy link
Owner

Thanks for working on this. This needs a test.

@sindresorhus
Copy link
Owner

I also don't think we should have ad-hoc handling for each property of Request. We need some common logic that merges request properties and options in a more general way.

@crisshaker
Copy link
Contributor Author

I also don't think we should have ad-hoc handling for each property of Request. We need some common logic that merges request properties and options in a more general way.

I totally agree with this. Is there something similar in place I could reference?

@sholladay
Copy link
Collaborator

We need some common logic that merges request properties and options in a more general way.

That's why we normalize them here with new Request(input, options).

The only special cases I can think of that are not handled naturally by that normalization are:

  • For Ky to set a request option's default value, we must only apply the default if input does not already have that option, otherwise our default will override it. We don't really have any such defaults at the moment (but we did in the past and I've proposed a default for mode in PR Change default request mode to same-origin #602).
  • For headers, Ky merges input and options, which is something that fetch() does not do (with fetch(), providing any headers in options replaces all headers in input).
  • For signal, Ky needs to not only apply a default, but override any existing signal that was provided in input or options. We do this so we can have our own AbortController for timing out the request, as fetch() doesn't have a built-in timeout option.
  • For duplex, Ky always sets it to half if the environment supports request streams. This is done because you can't use request streams without it. IMO, it ought to be a built-in default but I guess they wanted to make it explicit.
  • For credentials, Ky used to set a default value but PR fix: support cloudflare workers #559 changed It to undefined. We should be able to remove all special handling and references to it now, I think this was just overlooked during code review.

There isn't much that these cases have in common. But if anyone can think of a cleaner way to do all of this, I'd love to see it!

In this particular case with signal, we already modify the options object here. There's no need to do it twice. The correct fix is simply to update originalSignal to also check input.signal.

@sholladay
Copy link
Collaborator

I updated the code to use the simpler approach that I mentioned. PTAL.

Once a test is added, this should be good to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants