@@ -25,12 +25,14 @@ type ErrorType =
2525 | 'dns-error'
2626 | 'connection-refused'
2727 | 'connection-reset'
28+ | 'client-abort'
2829 | 'server-timeout'
2930 | 'client-timeout'
3031 | 'invalid-http-version'
3132 | 'invalid-method'
32- | 'unparseable-url'
33- | 'unparseable'
33+ | 'client-unparseable-url'
34+ | 'client-unparseable'
35+ | 'server-unparseable'
3436 | 'header-overflow'
3537 | 'invalid-headers'
3638 | 'unknown' ;
@@ -70,17 +72,25 @@ export function tagsToErrorType(tags: string[]): ErrorType | undefined {
7072 if ( tags . includes ( "passthrough-error:ECONNREFUSED" ) ) return 'connection-refused' ;
7173 if ( tags . includes ( "passthrough-error:ECONNRESET" ) ) return 'connection-reset' ;
7274 if ( tags . includes ( "passthrough-error:ETIMEDOUT" ) ) return 'server-timeout' ;
75+ if (
76+ tags . includes ( "passthrough-error:HPE_INVALID_CONSTANT" ) ||
77+ tags . includes ( "passthrough-error:ERR_INVALID_HTTP_TOKEN" ) ||
78+ tags . includes ( "passthrough-error:ERR_HTTP_INVALID_STATUS_CODE" ) ||
79+ tags . includes ( "passthrough-error:ERR_INVALID_CHAR" )
80+ ) {
81+ return 'server-unparseable' ;
82+ }
7383
7484 if ( tags . includes ( "http-2" ) || tags . includes ( "client-error:HPE_INVALID_VERSION" ) ) {
7585 return 'invalid-http-version' ;
7686 }
7787
7888 if ( tags . includes ( "client-error:HPE_INVALID_METHOD" ) ) return 'invalid-method' ; // QWE / HTTP/1.1
79- if ( tags . includes ( "client-error:HPE_INVALID_URL" ) ) return 'unparseable-url' ; // http://<unicode>
89+ if ( tags . includes ( "client-error:HPE_INVALID_URL" ) ) return 'client- unparseable-url' ; // http://<unicode>
8090 if (
8191 tags . includes ( "client-error:HPE_INVALID_CONSTANT" ) || // GET / HTTQ <- incorrect constant char
8292 tags . includes ( "client-error:HPE_INVALID_EOF_STATE" ) // Unexpected 0-length packet in parser
83- ) return 'unparseable' ; // ABC/1.1
93+ ) return 'client- unparseable' ; // ABC/1.1
8494 if ( tags . includes ( "client-error:HPE_HEADER_OVERFLOW" ) ) return 'header-overflow' ; // More than ~80KB of headers
8595 if (
8696 tags . includes ( "client-error:HPE_INVALID_CONTENT_LENGTH" ) ||
@@ -91,6 +101,10 @@ export function tagsToErrorType(tags: string[]): ErrorType | undefined {
91101 ) return 'invalid-headers' ;
92102
93103 if ( tags . includes ( "client-error:ERR_HTTP_REQUEST_TIMEOUT" ) ) return 'client-timeout' ;
104+ if (
105+ tags . includes ( "client-error:ECONNABORTED" ) ||
106+ tags . includes ( "client-error:EPIPE" )
107+ ) return 'client-abort' ;
94108
95109 if (
96110 tags . filter ( t => t . startsWith ( "passthrough-error:" ) ) . length > 0 ||
@@ -108,15 +122,15 @@ function typeCheck<T extends string>(types: readonly T[]) {
108122const isInitialRequestError = typeCheck ( [
109123 'invalid-http-version' ,
110124 'invalid-method' ,
111- 'unparseable' ,
112- 'unparseable-url' ,
125+ 'client- unparseable' ,
126+ 'client- unparseable-url' ,
113127 'header-overflow' ,
114128 'invalid-headers'
115129] ) ;
116130
117131const isClientBug = typeCheck ( [
118- 'unparseable' ,
119- 'unparseable-url' ,
132+ 'client- unparseable' ,
133+ 'client- unparseable-url' ,
120134 'invalid-headers'
121135] ) ;
122136
@@ -132,6 +146,11 @@ const wasNotForwarded = typeCheck([
132146 'connection-refused'
133147] ) ;
134148
149+ const wasResponseIssue = typeCheck ( [
150+ 'server-unparseable' ,
151+ 'connection-reset'
152+ ] ) ;
153+
135154const wasTimeout = typeCheck ( [
136155 'client-timeout' ,
137156 'server-timeout'
@@ -192,11 +211,11 @@ export const HttpErrorHeader = (p: {
192211 ? 'used an unsupported HTTP version'
193212 : p . type === 'invalid-headers'
194213 ? 'included an invalid or unparseable header'
195- : p . type === 'unparseable-url'
214+ : p . type === 'client- unparseable-url'
196215 ? 'included an unparseable URL'
197216 : p . type === 'header-overflow'
198217 ? 'headers were too large to be processed'
199- : p . type === 'unparseable'
218+ : p . type === 'client- unparseable'
200219 ? 'could not be parsed'
201220 : new UnreachableCheck ( p . type )
202221 } , so HTTP Toolkit did not handle this request.
@@ -233,15 +252,25 @@ export const HttpErrorHeader = (p: {
233252 : new UnreachableCheck ( p . type )
234253 }
235254 </ >
236- : p . type === 'unknown' || p . type === 'connection-reset'
255+ : p . type === 'client-abort'
256+ ? < >
257+ The client unexpectedly disconnected during the request, so
258+ the response could not be completed.
259+ </ >
260+ : wasResponseIssue ( p . type )
237261 ? < >
238- The request failed because {
262+ The upstream request failed because {
239263 p . type === 'connection-reset'
240264 ? 'the connection to the server was reset'
241- : p . type === 'unknown '
242- ? 'of an unknown error '
265+ : p . type === 'server-unparseable '
266+ ? 'the response from the server was unparseable '
243267 : new UnreachableCheck ( p . type )
244- } , so HTTP Toolkit could not return a response.
268+ } , so HTTP Toolkit could not return a response to the client.
269+ </ >
270+ : p . type === 'unknown'
271+ ? < >
272+ The request failed because of an unknown error,
273+ so HTTP Toolkit could not return a response.
245274 </ >
246275 : new UnreachableCheck ( p . type )
247276 }
@@ -336,6 +365,12 @@ export const HttpErrorHeader = (p: {
336365 the request. You can also mock requests like this, to avoid sending them upstream
337366 at all.
338367 </ HeaderText >
368+ : p . type === 'client-abort'
369+ ? < HeaderText >
370+ This could be due to connection issues, general problems in the client, or that
371+ the client simply no longer wanted to receive the response and closed the
372+ connection intentionally.
373+ </ HeaderText >
339374 : p . type === 'client-timeout'
340375 ? < HeaderText >
341376 This could be due to connection issues, general problems in the client, or delays
@@ -355,6 +390,12 @@ export const HttpErrorHeader = (p: {
355390 not follow the HTTP spec. That suggests either a major bug in the client, or that
356391 they're not sending HTTP at all.
357392 </ HeaderText >
393+ : p . type === 'server-unparseable'
394+ ? < HeaderText >
395+ This means the server sent HTTP Toolkit some fundamentally invalid data that does
396+ not follow the HTTP spec. That suggests either a major bug in the server, or that
397+ they're not sending HTTP at all.
398+ </ HeaderText >
358399 : p . type === 'header-overflow'
359400 ? < HeaderText >
360401 { desktopVersion . value && advancedHeaderOverflowSupported
0 commit comments