-
-
Notifications
You must be signed in to change notification settings - Fork 127
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(ClientRequest): ignore request destroyed state when responding with a mocked response #432
Conversation
kettanaito
commented
Sep 18, 2023
•
edited
Loading
edited
- Fixes Responses with delay hang forever with "got" #426
0569526
to
fd0c588
Compare
You may want to try an address that does not exist like: nowhere.com it.only('supports timeout before resolving request as-is', async () => {
interceptor.on('request', async ({request}) => {
await sleep(750)
})
const requestStart = Date.now()
const res = await got('http://test.example',{ retry: 0 })
const requestEnd = Date.now()
expect(res.statusCode).toBe(200)
expect(res.body).toBe(`{"id":1}`)
expect(requestEnd - requestStart).toBeGreaterThan(700)
}) |
I found it to be related to the Oh, one more thing: |
Where it doesn't await? Also, You can pass |
Talking about this
Good point. But we should support the default behavior with retries as well. This is so unexpected I'm not ruling out code transformations by Vitest. We need to check if delay in request listeners functions correctly with other interceptors to narrow down the problematic area (it's likely the interceptors/src/utils/emitAsync.ts Lines 22 to 24 in 1b6b058
|
Root causeI found the root cause for this. This line in
Because that function is not |
Alas, the issue with But, the |
Looking into
|
@kettanaito When debugging it, I saw that the
I think so
I looked in this direction, and it seems like |
Root cause & The fix@mikicho, yes! You've found it as well. I added a setter to destroyed (not aborted) on The Got test is now passing. |
0bd1cac
to
a9f17e5
Compare
@mikicho, would you have a minute to review these changes? I could use your eyes on this 🙏 |
* @note Ignore this request being destroyed by TLS in Node.js | ||
* due to connection errors. | ||
*/ | ||
this.destroyed = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of ignoring the failed request, can we handle the error by monkey-patching whatever is needed? This may not be urgent, and the issue may be resolved when/if we implement mocking at the socket level.
(#375)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what we could monkey-patch in this case though.
This assignment happens only for mocked responses. When you have a mock response returned, it shouldn't matter if there's been connection errors or not. This way we can keep the original connection logic from Node (handy for when you don't have mocked responses) but ignore any errors that occurred because they are irrelevant when providing a mock response.
Note that we still do the following:
- Capture any errors occurring during the request, which includes connection errors;
- If the consumer hasn't responded to the request, we replay those errors so they are never ignored when the request was performed as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that Socket-based interception is largely not worth it (see #399). It's way too low-level and the benefits it provides aren't worth the cost (having to tap so deep you end up re-implementing Node buffer encoding methods since those aren't public).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment happens only for mocked responses...
I'm not an expert, but what if you want mock connection-related behavior, for example, Nock lets you mock delay in the connection and mock delay in the response.
Anyway, this is another feature or something anyway, so LGTM.
If the consumer hasn't responded to the request, we replay those errors so they are never ignored when the request was performed as-is.
Side question: Why can't we first check if there is a mocked response and only if negative, forward this to the real NodeClient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having more fine-grained delays would certainly be a feature worth exploring. For now, whichever delays you specify in the request listener are treated as response delays (they trigger after the connection has been made and the request has been written).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
We will probably need to to keep parity with what Nock have now if we want to move Nock to mswjs/interceptors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's raise this as a new feature request and discuss it in more detail.
Released: v0.25.3 🎉This has been released in v0.25.3! Make sure to always update to the latest version ( Predictable release automation by @ossjs/release. |