Skip to content

Commit 1771c2e

Browse files
committed
fix: Improve exception handling and response parsing
Refined error handling in `DefaultResponseProcess` (net.ts): - For non-OK HTTP responses: - Robustly extracts error messages by attempting to parse the response body first as JSON, then as text, using `response.clone()` before each attempt to prevent stream consumption issues. - Logs intermediate parsing failures to `console.debug`. - Throws a more informative error message. - For OK HTTP responses: - When falling back to text after a `response.json()` failure, enhanced `console.debug` logging and comments to clarify that this is intentional content negotiation. These changes aim to satisfy static analysis tools regarding unhandled exceptions by making error handling more explicit, logging relevant information, and clarifying intent in catch blocks.
1 parent 353f02e commit 1771c2e

File tree

1 file changed

+45
-15
lines changed
  • console/atest-ui/src/views

1 file changed

+45
-15
lines changed

console/atest-ui/src/views/net.ts

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,64 @@ async function DefaultResponseProcess(response: any): Promise<any> {
2929
if (!response.ok) {
3030
switch (response.status) {
3131
case 401:
32-
throw new Error("Unauthenticated")
32+
throw new Error("Unauthenticated");
33+
// Potentially add other specific status code handling here
3334
}
3435

36+
// For non-OK responses, attempt to parse error details from the body
37+
let errorMessage = `Request failed with status ${response.status}`;
38+
const clonedResponseForErrorJson = response.clone();
3539
try {
36-
const message = await response.json().then((data: any) => data.message)
37-
throw new Error(message)
38-
} catch {
39-
const text = await response.text()
40-
throw new Error(text)
40+
const errorData = await clonedResponseForErrorJson.json();
41+
errorMessage = errorData?.message || JSON.stringify(errorData);
42+
} catch (jsonError: any) {
43+
console.debug(
44+
`Error response body (status ${response.status}) was not valid JSON. Attempting to read as text. JSON parse error:`,
45+
jsonError
46+
);
47+
// Body consumed by failed .json() attempt on clone, try .text() on a new clone of original response
48+
const clonedResponseForErrorText = response.clone();
49+
try {
50+
const textData = await clonedResponseForErrorText.text();
51+
if (textData) {
52+
errorMessage = textData;
53+
} else {
54+
errorMessage = `Request failed with status ${response.status} (empty error body).`;
55+
}
56+
} catch (textError: any) {
57+
console.debug(
58+
`Error response body (status ${response.status}) also failed to be read as text. Text parse error:`,
59+
textError
60+
);
61+
// Fallback error message if body is entirely unreadable
62+
errorMessage = `Request failed with status ${response.status} and error body was unreadable.`;
63+
}
4164
}
65+
throw new Error(errorMessage);
4266
}
4367

44-
// Check if the content type is explicitly text/plain
68+
// For OK responses, handle content based on Content-Type
4569
const contentType = response.headers.get('Content-Type') ?? '';
4670
if (contentType.startsWith('text/plain')) {
47-
// For text/plain, directly return the text without parsing
71+
// For text/plain, directly return the text
4872
return await response.text();
4973
}
5074

51-
// For all other types, try parsing as JSON first
75+
// For all other types (or if Content-Type is missing/unexpected), try parsing as JSON first
5276
try {
5377
return await response.json();
54-
} catch (e) {
55-
// If JSON parsing fails, get the text content as fallback
56-
console.debug("Response is not JSON despite content type, handling as plain text");
57-
// We have to get a clone since the body stream was already consumed
58-
const clonedResponse = response.clone();
59-
return await clonedResponse.text();
78+
} catch (jsonParseError: any) {
79+
// This catch block is an intentional part of the content negotiation.
80+
// If the response, despite its Content-Type (or lack thereof), isn't valid JSON,
81+
// we fall back to treating it as plain text. The original error is logged for debugging.
82+
console.debug(
83+
`Response body was not valid JSON (Content-Type: '${contentType}'). Falling back to plain text. JSON parse error:`,
84+
jsonParseError
85+
);
86+
// The body stream was already consumed by the failed response.json() attempt.
87+
// A clone of the original response is needed to read the body as text.
88+
const clonedResponseForTextFallback = response.clone();
89+
return await clonedResponseForTextFallback.text();
6090
}
6191
}
6292

0 commit comments

Comments
 (0)