spebbe / dartz

Functional programming in Dart
MIT License
756 stars 59 forks source link

exception in function is not caught in attempt #33

Closed harishrathi closed 4 years ago

harishrathi commented 4 years ago

I have all my API calls returning Either<ApiException, Result> e.g.

  Future<Either<ApiException, SendOtpDto>> receiveOtp(
      String phoneNumber) async {
    return Task<SendOtpDto>(() async {
      final String url = 'AuthenticationApi/sendOtp/$phoneNumber';
      final Map<String, dynamic> response = await apiWrapper.get(url);
      final SendOtpDto dto = SendOtpDto.fromJson(response);
      if (!dto.success) {
        throw ServerErrorException(dto.error);
      }
      return dto;
    }).attempt().mapLeftToFailure().run();
  }

But if exception is thrown inside a function, like below

      if (!dto.success) {
        throw ServerErrorException(dto.error);
      }

Then attempt() should catch them as ApiException. Currently it gives error type 'Future<Either<ApiException, dynamic>>' is not a subtype of type 'FutureOr<Either<ApiException, SendOtpDto>>

This is how I am calling the API

    if (event is GetOtpButtonPressed) {
      yield LoginApiLoading();
      final Either<ApiException, SendOtpDto> result = await apiManager.authentication(context).receiveOtp(event.username);
      yield result.fold((ApiException exception) {
        return LoginFailure(error: exception.toString());
      }, (SendOtpDto dto) {
        return LoginOtpSent(dto: dto);
      });
    }
mateusfccp commented 4 years ago

I couldn't test your code because you didn't give a minimal reproducible example.

However, I got similar error sometimes when Dart couldn't infer the type. This may be the case, as pointed by the dynamic in the error.

Try passing the type explicitily to .attempt<T>.

harishrathi commented 4 years ago

That helped. Closing the issue.

spebbe commented 4 years ago

Great! Thanks for helping, @mateusfccp!