Conversation
Use a shared response handler for Meshery and cloud RTK base queries that parses JSON when possible and otherwise returns the raw text body. This avoids PARSING_ERROR failures when servers return text or mislabeled content during error flows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Lee Calcote <lee.calcote@layer5.io>
There was a problem hiding this comment.
Pull request overview
This PR updates the shared RTK Query base queries for both Meshery and Cloud to preserve non-JSON response bodies (especially error bodies) by introducing a custom responseHandler that attempts JSON parsing and falls back to returning raw text.
Changes:
- Added a shared
parseBaseQueryResponsehandler to parse JSON when possible and otherwise return raw response text. - Wired the custom
responseHandlerinto both Cloud and MesheryfetchBaseQueryconfigurations.
|
|
||
| if (!text) { | ||
| return null; | ||
| } | ||
|
|
||
| try { | ||
| return JSON.parse(text); | ||
| } catch { | ||
| return text; | ||
| } |
There was a problem hiding this comment.
parseBaseQueryResponse attempts JSON.parse on every non-empty body, regardless of Content-Type. This will coerce valid JSON scalars like 0, true, or null into non-string values even when the server returns text/plain (your OpenAPI specs define several text/plain responses as type: string). Consider keying JSON parsing off response.headers.get('content-type') (e.g., application/json / +json) or at least a cheap heuristic like trim() + leading {/[ to avoid mis-parsing plain-text responses; also treat whitespace-only bodies as empty via trim().
| if (!text) { | |
| return null; | |
| } | |
| try { | |
| return JSON.parse(text); | |
| } catch { | |
| return text; | |
| } | |
| const trimmedText = text.trim(); | |
| if (!trimmedText) { | |
| return null; | |
| } | |
| const contentType = response.headers.get("content-type")?.toLowerCase() ?? ""; | |
| const isJsonResponse = contentType.includes("application/json") || contentType.includes("+json"); | |
| if (isJsonResponse) { | |
| try { | |
| return JSON.parse(text); | |
| } catch { | |
| return text; | |
| } | |
| } | |
| return text; |
There was a problem hiding this comment.
Code Review
This pull request introduces a custom response handler, parseBaseQueryResponse, to manage empty or non-JSON responses for the RTK Query base queries. The feedback suggests refining the error handling within this function to specifically catch SyntaxError during JSON parsing, ensuring that other potential runtime errors are not inadvertently suppressed.
| const parseBaseQueryResponse = async (response: Response) => { | ||
| const text = await response.text(); | ||
|
|
||
| if (!text) { | ||
| return null; | ||
| } | ||
|
|
||
| try { | ||
| return JSON.parse(text); | ||
| } catch { | ||
| return text; | ||
| } | ||
| }; |
There was a problem hiding this comment.
The parseBaseQueryResponse function uses a generic try-catch block that catches all errors. It is better to specifically catch SyntaxError when parsing JSON to avoid masking other potential runtime errors.
const parseBaseQueryResponse = async (response: Response) => {
const text = await response.text();
if (!text) {
return null;
}
try {
return JSON.parse(text);
} catch (e) {
if (e instanceof SyntaxError) {
return text;
}
throw e;
}
};
Summary
Testing