Skip to content

Commit

Permalink
Handle the new HTTP request timeout errors
Browse files Browse the repository at this point in the history
These are new in Node 18 / server 1.12.7, which will drop requests
that fail to send headers after 1 minute or a body after 5 minutes.
  • Loading branch information
pimterry committed Jun 27, 2023
1 parent 7723d61 commit 1d6ecd0
Showing 1 changed file with 27 additions and 6 deletions.
33 changes: 27 additions & 6 deletions src/components/view/http/http-error-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ type ErrorType =
| 'dns-error'
| 'connection-refused'
| 'connection-reset'
| 'timeout'
| 'server-timeout'
| 'client-timeout'
| 'invalid-http-version'
| 'invalid-method'
| 'unparseable-url'
Expand Down Expand Up @@ -66,7 +67,7 @@ export function tagsToErrorType(tags: string[]): ErrorType | undefined {
if (tags.includes("passthrough-error:EAI_AGAIN")) return 'dns-error';
if (tags.includes("passthrough-error:ECONNREFUSED")) return 'connection-refused';
if (tags.includes("passthrough-error:ECONNRESET")) return 'connection-reset';
if (tags.includes("passthrough-error:ETIMEDOUT")) return 'timeout';
if (tags.includes("passthrough-error:ETIMEDOUT")) return 'server-timeout';

if (tags.includes("http-2") || tags.includes("client-error:HPE_INVALID_VERSION")) {
return 'invalid-http-version';
Expand All @@ -87,6 +88,8 @@ export function tagsToErrorType(tags: string[]): ErrorType | undefined {
tags.includes("passthrough-error:HPE_INVALID_HEADER_TOKEN") // Invalid headers upstream, e.g. after breakpoint
) return 'invalid-headers';

if (tags.includes("client-error:ERR_HTTP_REQUEST_TIMEOUT")) return 'client-timeout';

if (
tags.filter(t => t.startsWith("passthrough-error:")).length > 0 ||
tags.filter(t => t.startsWith("client-error:")).length > 0
Expand Down Expand Up @@ -126,6 +129,11 @@ const wasNotForwarded = typeCheck([
'connection-refused'
]);

const wasTimeout = typeCheck([
'client-timeout',
'server-timeout'
]);

const isWhitelistable = typeCheck([
'untrusted',
'expired',
Expand All @@ -139,7 +147,7 @@ const isMockable = typeCheck([
'dns-error',
'connection-refused',
'connection-reset',
'timeout'
'server-timeout'
]);

export const HttpErrorHeader = (p: {
Expand Down Expand Up @@ -204,13 +212,20 @@ export const HttpErrorHeader = (p: {
'refused the connection'
}, so HTTP Toolkit did not forward the request.
</>
: wasTimeout(p.type)
? <>
The request timed out {
p.type === 'client-timeout'
? 'waiting for the client to send the complete request'
: // server-timeout:
'waiting for a response from the server'
}
</>
: // Unknown/upstream issue:
<>
The request failed because {
p.type === 'connection-reset'
? 'the connection to the server was reset'
: p.type === 'timeout'
? 'the connection to the server timed out'
: // unknown
'of an unknown error'
}, so HTTP Toolkit could not return a response.
Expand Down Expand Up @@ -307,7 +322,13 @@ export const HttpErrorHeader = (p: {
the request. You can also mock requests like this, to avoid sending them upstream
at all.
</HeaderText>
: p.type === 'timeout'
: p.type === 'client-timeout'
? <HeaderText>
This could be due to connection issues, general problems in the client, or delays
generating the complete body of the request. This might be resolved by retrying
the request, or sending a simpler request with a smaller or easier to generate body.
</HeaderText>
: p.type === 'server-timeout'
? <HeaderText>
This could be due to connection issues, general issues on the server, or issues
with handling this request specifically. This might be resolved by retrying
Expand Down

0 comments on commit 1d6ecd0

Please sign in to comment.