-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Description
When Options.responseType is set to ResponseType.json, Dio attempts to decode the response body using the default transformer (FusedTransformer). However, if a server-side crash occurs (e.g., a 500 Internal Server Error), the server often returns a standard HTML error page while maintaining a Content-Type: application/json header.
Because the body is HTML (starting with <), jsonDecode throws: FormatException: Unexpected character (at offset 0)
Currently, when this happens, the resulting DioException makes it difficult to retrieve the original HTML string. This is a major pain point for debugging, as the HTML body usually contains the stack trace or error reason from the web server.
Current Behavior
- Request is made with
ResponseType.json. - Server responds with a 500 Error and an HTML body, but still sends
Content-Type: application/json. FusedTransformerfails to parse the HTML as JSON.- A
FormatExceptionis thrown. - The developer receives a
DioException, but response is null.
Expected Behavior
Even if JSON decoding fails, the DioException should:
- Capture the raw response body.
- Populate
DioException.response.datawith the original String. - Allow the developer to see the server's HTML output to diagnose the 500 error.
Solution Brainstorm (Minimal Idea)
The FusedTransformer.transformResponse should be modified to catch FormatException during JSON decoding and fallback to the raw string.
- For the Fast Path
try {
return await _fastUtf8JsonDecode(options, responseBody);
} catch (e) {
// If the response is not JSON and no custom decoder was specified,
// assume it is an utf8 string
final responseBytes = await consolidateBytes(responseBody.stream);
return utf8.decode(responseBytes, allowMalformed: true);
}- For the Slow Path
if (isJsonContent && decodedResponse != null) {
try {
return jsonDecode(decodedResponse);
} catch (e) {
// If the custom decoder produced a string that isn't valid JSON,
// return the raw string so it's accessible in DioException.response.data
return decodedResponse;
}
}The Challenge:
While returning the raw string solves the problem of accessing the data, the developer should still be notified that the response was not valid JSON. We need a solution that preserves the raw data without losing the 'Invalid JSON' error state.