Sometimes, the back-end changes the response structure unexpectedly. For example, our app expects this:
{
"id": "0",
"name": "Name"
}
but we get this instead:
{
"id": 0,
"name": "Name"
}
Logging these discrepancies would be really useful. To make the logs as helpful as possible, we need to capture:
Request details (path, URI, params, etc.);
Parsing error details (we can use CheckedFromJsonException from json_serializable).
The most logical place for such logging is within the client.
Solution
Let's introduce a new entity - ParseErrorLogger :
import 'package:dio/dio.dart';
/// Base class for logging errors that occur during parsing of response data.
abstract class ParseErrorLogger {
/// Logs an error that occurred during parsing of response data.
///
/// - [error] is the error that occurred.
/// - [stackTrace] is the stack trace of the error.
/// - [options] are the options that were used to make the request.
void logError(Object error, StackTrace stackTrace, RequestOptions options);
}
This entity can be injected into our client:
import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';
part 'rest_client.g.dart';
@RestApi()
abstract class RestClient {
/// API creation factory using [Dio].
factory RestClient(
Dio dio, {
String baseUrl,
ParseErrorLogger? errorLogger,
}) = _RestClient;
@GET('')
Future<SomeDto> someRequest();
}
And this entity will be called if parsing fails.
For example, this is rest_client.g.dart. As shown in the After example, errorLogger is called if there are any issues with parsing:
Before
After
```dart
@override
Future someRequest() async {
const _extra = {};
final queryParameters = {};
final _headers = {};
final Map? _data = null;
final _result = await _dio.fetch
Problem
Sometimes, the back-end changes the response structure unexpectedly. For example, our app expects this:
but we get this instead:
Logging these discrepancies would be really useful. To make the logs as helpful as possible, we need to capture:
CheckedFromJsonException
fromjson_serializable
).The most logical place for such logging is within the client.
Solution
Let's introduce a new entity -
ParseErrorLogger
:This entity can be injected into our client:
And this entity will be called if parsing fails.
For example, this is
rest_client.g.dart
. As shown in theAfter
example,errorLogger
is called if there are any issues with parsing: