Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(generator): Add ParseErrorLogger #680

Merged

Conversation

Sadhorsephile
Copy link
Contributor

Problem

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
  @override
  Future<SomeDto> someRequest() async {
    const _extra = <String, dynamic>{};
    final queryParameters = <String, dynamic>{};
    final _headers = <String, dynamic>{};
    final Map<String, dynamic>? _data = null;
    final _result = await _dio.fetch<Map<String, dynamic>>(_setStreamType<SomeDto>(Options(
      method: 'GET',
      headers: _headers,
      extra: _extra,
    )
        .compose(
          _dio.options,
          '',
          queryParameters: queryParameters,
          data: _data,
        )
        .copyWith(
            baseUrl: _combineBaseUrls(
          _dio.options.baseUrl,
          baseUrl,
        ))));
    final value = SomeDto.fromJson(_result.data!);
    return value;
  }
  @override
  Future<SomeDto> someRequest() async {
    final _extra = <String, dynamic>{};
    final queryParameters = <String, dynamic>{};
    final _headers = <String, dynamic>{};
    const Map<String, dynamic>? _data = null;
    final options = _setStreamType<SomeDto>(Options(
      method: 'GET',
      headers: _headers,
      extra: _extra,
    )
        .compose(
          _dio.options,
          '',
          queryParameters: queryParameters,
          data: _data,
        )
        .copyWith(
            baseUrl: _combineBaseUrls(
          _dio.options.baseUrl,
          baseUrl,
        )));
    final _result = await _dio.fetch<Map<String, dynamic>>(options);
    late SomeDto value;
    try {
      value = SomeDto.fromJson(_result.data!);
    } on Object catch (e, s) {
      errorLogger?.logError(e, s, options);
      rethrow;
    }
    return value;
  }

@trevorwang trevorwang merged commit 27ffbfc into trevorwang:master Jul 1, 2024
0 of 2 checks passed
trevorwang added a commit that referenced this pull request Jul 1, 2024
trevorwang added a commit that referenced this pull request Jul 1, 2024
@trevorwang
Copy link
Owner

please fix the unit test failure

@trevorwang
Copy link
Owner

/reopen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants