Fix extend() dropping numeric retry limit when merging with an object#867
Fix extend() dropping numeric retry limit when merging with an object#867chatman-media wants to merge 2 commits into
extend() dropping numeric retry limit when merging with an object#867Conversation
|
I think this needs a small tweak. The new retry shorthand handling runs inside the generic recursive merge, so it can also affect user data, not just the top-level option. For example, this now rewrites the JSON payload: ky.create({
method: 'post',
json: {retry: 3},
}).extend({
json: {retry: {foo: 'bar'}},
});The request body becomes: {"retry":{"limit":3,"foo":"bar"}}I would expect it to stay: {"retry":{"foo":"bar"}}So the special-case probably needs to be scoped to the root options merge. I manually verified the current behavior with a custom fetch that reads the outgoing POST body, so this is not just a helper-level concern. Also worth adding this as a regression test so we don't accidently rewrite arbitrary payload data with a |
|
Good catch — fixed in 61b90ed. The shorthand expansion is now scoped to the root options merge via an Added your exact example as a regression test (asserting the outgoing POST body via the test server): it fails before the change ( |
Problem
retryaccepts a number as shorthand for{limit: number}(per the docs: "Ifretryis a number, it will be used aslimitand other defaults will remain in place.").However, when a numeric
retryis set on a parent instance and then extended with an object, the numeric limit is silently dropped and falls back to the default (2):The reverse direction (object on the parent, number on the child) and the all-object case both work correctly — only the number → object merge loses data.
Cause
In
deepMerge,retryis merged like any other nested object. When the parent value is the numeric shorthand (3) and the incoming value is an object, the recursion ends up asdeepMerge(3, {methods: ['get']}). A non-object source is skipped entirely bydeepMerge, so the3is discarded and only{methods: ['get']}survives — the limit is lost.Fix
Expand the numeric
retryshorthand to{limit: number}before the deep merge, so extending it with an object preserves the limit. This mirrors the documented shorthand semantics and leaves every other case (object → object, object → number replacement,replaceOption) unchanged.Test
Added a test in
test/retry.tsthat setsretry: 3on a parent, extends it withretry: {methods: ['get']}, and asserts the request is attemptedlimit + 1times. It fails onmain(3 attempts) and passes with the fix (4 attempts).