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

Add ability to stop retries in beforeRetry hooks #198

Merged
merged 9 commits into from
Nov 15, 2019

Conversation

whitecrownclown
Copy link
Contributor

Hello,

This is related to the discussion from #185.

Summary of the PR:

  • exported a new Symbol NO_RETRY_SYMBOL
  • the Symbol can be imported & returned from a beforeRetry hook in order to abandon retries
  • I'm unsure if an error should be thrown even if you have throwHttpErrors enabled
  • added test & tsd

@sholladay @sindresorhus
Thoughts?

Thank you!

index.js Outdated
this._options,
error,
this._retryCount,
beforeRetryResults.add(
Copy link
Collaborator

@sholladay sholladay Nov 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more consistent with the behavior of our other hooks if returning the symbol short-circuited the loop. Meaning, return immediately inside of the loop, preventing any further beforeRetry hooks from running.

That also removes the need to use a Set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure about that, my reasoning was that you'd want to have all your hooks running before making the "cancel retry" decision.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get what you are saying. I do see how this case is a bit different, as the symbol is not a true "value" being returned by the hook, unlike the other cases where a hook may return a Request or Response instance.

Still, I think it would be surprising for beforeRetry to behave differently in this respect than the other hook types. IMO, we need to have a holistic approach on whether returning a value from a hook short-circuits the chain. And we should apply that logic consistently.

index.js Outdated Show resolved Hide resolved
index.d.ts Outdated Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
test/hooks.js Outdated Show resolved Hide resolved
index.d.ts Outdated Show resolved Hide resolved
@sindresorhus
Copy link
Owner

It also needs to be documented in the readme.

@sindresorhus sindresorhus changed the title [Feature] Add possiblity to stop retries from beforeRetry hooks Add ability to stop retries in beforeRetry hooks Nov 8, 2019
@sindresorhus
Copy link
Owner

@sholladay Looks good to you?

index.d.ts Outdated

@example
```
import ky, {stop as kyStop} from 'ky';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd name it RETRY_STOP.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We went with something generic so we can use the symbol for other places we want to support stopping.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, then it should be SYMBOL_STOP or symbol_stop IMO :P

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stop is too general I think

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like hungarian notation. Prefixing it with "symbol" doesn't make the intent any clearer.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. It's stop. Is it a function or what? Can I stop(ky(...))?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@szmarczak thankfully that will generate a TypeError. But I get your point. I have the same icky feelings about objects with plural names. I tend to reserve plural names for arrays and it can be confusing if there is no distinction in some APIs. Symbols add to the problem because they are often used to signal intent for an action, similar to a function, so the naming styles conflict. TypeScript and IntelliSense make this a bit more obvious, though.

index.d.ts Outdated Show resolved Hide resolved
@sindresorhus
Copy link
Owner

Any thoughts on making it a property on the default export instead of a named export? It doesn't really make sense on its own and ky.stop would make the intend clearer, instead of having to rename the named export to kyStop.

index.test-d.ts Outdated
@@ -25,6 +25,7 @@ expectType<typeof ky>(ky.create({}));
expectType<typeof ky>(ky.extend({}));
expectType<HTTPError>(new HTTPError(new Response));
expectType<TimeoutError>(new TimeoutError);
expectType<symbol>(stop);
Copy link
Collaborator

@sholladay sholladay Nov 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if it matters, but shouldn't this be Symbol (capitalized)?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it’s a primitive, so should be lowercased (both work, at least until I get XO working with ambient TS files).

Copy link
Collaborator

@sholladay sholladay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM aside from my nit here about Symbol: #198 (comment)

@whitecrownclown
Copy link
Contributor Author

Any thoughts on making it a property on the default export instead of a named export? It doesn't really make sense on its own and ky.stop would make the intend clearer, instead of having to rename the named export to kyStop.

I went ahead and made this change. I think it makes sense.

@sholladay
Copy link
Collaborator

Any thoughts on making it a property on the default export instead of a named export?

@sindresorhus I also prefer ky.stop instead of named export. 👍

What do you think about doing this for the other exports as well? I believe it would solve that Rollup warning during the build and make it easier for CommonJS users to import the package, as they should then be able to use ky directly instead of ky.default.

@sindresorhus
Copy link
Owner

What do you think about doing this for the other exports as well? I believe it would solve that Rollup warning during the build and make it easier for CommonJS users to import the package, as they should then be able to use ky directly instead of ky.default.

👍

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.

None yet

4 participants