Skip to content

DioError [DioErrorType.response]: Http status error [307] #0 DioMixin.assureDioError (package:dio/src/dio_mixin.dart:819:20) #1306

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

Closed
riccardopirani opened this issue Oct 28, 2021 · 29 comments

Comments

@riccardopirani
Copy link

riccardopirani commented Oct 28, 2021

New Issue Checklist

dio does not read the response of a rest call, below I leave an example of the json returning from

Issue Info

Error: r [DioErrorType.response]: Http status error [307]
#0      DioMixin.assureDioError (package:dio/src/dio_mixin.dart:819:20)
#1      DioMixin._dispatchRequest (package:dio/src/dio_mixin.dart:678:13)
<asynchronous suspension>
#2      DioMixin.fetch.<anonymous closure>.<anonymous closure> (package:dio/src/dio_mixin.dart)
<asynchronous suspension>

Platform Name iPhone 12 Pro Max
Platform Version iOS 15
Dio Version 4.0.0.
Xcode version 10.2.1
Repro rate all the time (100%)

Issue Description and Steps

Code:

Future<Utente> login(String email, String pwd) async {
    var ret;
    var map = {'email': email, 'password': pwd};
    try {
      print("url"+url);
      Dio _dio = new Dio();
      _dio.options.headers['content-Type'] = 'application/json';
      final responseData = await _dio.post<Map<String, dynamic>>(
          url + "/api/latest/Auth/Login",
          data: map);
      print("Response: " + responseData.data.toString());
    } catch (err) {
      print("Errore login: " + err.toString());
    }
    print("Value è vuoto");
    return new Utente();
  }

JSON return:


{
    "access_token": "xxxxx",
    "expires_in": 36000,
    "token_type": "Bearer",
    "refresh_token": "2CBBxxxxF3",
    "scope": "apiUniBooks offline_access"
}

@wendux
Copy link
Contributor

wendux commented Oct 31, 2021

307 is not regard as success,so throw error is expected..... I can't get what your problem is.

@markfili
Copy link

markfili commented Nov 3, 2021

I got here looking for the same answer but with 404 response status code. I think the problem is that it is not clear how to handle response errors in the new version of Dio. Previous versions worked with try-catch but this new version throws errors before they get to where we called a Dio request method. I believe the solution is to implement an interceptor with a handler in onError method and handle or pass the response as is to be caught with custom try-catch logic; as seen here https://github.com/flutterchina/dio/blob/16c6da8514008a012f713c14275d04aab28e6bf7/example/response_interceptor.dart can you maybe update the readme with how to properly handle or catch Dio errors in the new version?

@markfili
Copy link

markfili commented Nov 4, 2021

@wendux
a response error needs to be explicitly rejected in the 4.0.x version of Dio, that is what is confusing people.
here's how the error gets propagated to existing try-catch blocks:

var dioClient = Dio();
dioClient.interceptors.add(InterceptorsWrapper(onError: (error, handler) {
      if (error != null) {
        // use the handler to propagate error
        handler.reject(error);
      }
    }));

if you have any better way to handle this, please share

@a7md0
Copy link

a7md0 commented Nov 12, 2021

This seems related to #1171

@markfili Could your elaborate more? I tried to use the interceptor you provided but still having the same exception thrown even though the call is sounded with try/catch

  • Why the try/catch won't catch the response error?
  • The documentation does not talk about different strategy to handle response error other than the try/catch

@markfili
Copy link

@a7md0 good job on finding all those related issues, I'm impressed!

I think that, at the moment, maintainers don't really understand what our problem is and I believe we're experiencing something that has to do with how Future handles error. I'm not 100% certain or knowledgable on what is going on, but what is going on reminds me of errors being thrown in another thread so they don't appear in our try/catch block. I think you could play around with methods catchError and onError on Dio's request methods and see if that catches the exceptions in question. does any of this make any sense to you?

my problems were seemingly solved by adding that interceptor which allowed the DioError to propagate to the try-catch block where I expected it to arrive; logs still show it throws the assureDioError stacktrace in the "background" but at least the error is passed and caught by the main program, too. are you having the same results?

I'm open to help and investigate further.

@a7md0
Copy link

a7md0 commented Nov 13, 2021

@markfili Thanks for following up.

I have tried to supply catchError on the call, but still the unhandled exception is not caught directly. Here is the order while debugging:

  1. The throw statement from dio_mixin.dart line 678 throw assureDioError(e, reqOpt); (does get thrown even the call is surrounded by try/catch block)
  2. The catchError path on the actual call (I've added breakpoint here to see when it get executed)
  3. The on DioError catch (dioError) block (I've added breakpoint here to see when it get executed)
    try {
      var httpClient = Dio()..options.contentType = "application/json";

      var response = await httpClient
          .get(
        "https://gorest.co.in/public/v1/posts/nonExistingId",
      )
          .catchError((e) {
        print("Future.catchError: ${e.toString()}");
      });

    } on DioError catch (dioError) {
      print("DioError catch: ${dioError.message}");
    } catch (e) {
      print("Other exception catch: ${e.toString()}");
    }

@markfili
Copy link

@markfili Thanks for following up.

I have tried to supply catchError on the call, but still the unhandled exception is not caught directly. Here is the order while debugging:

  1. The throw statement from dio_mixin.dart line 678 throw assureDioError(e, reqOpt); (does get thrown even the call is surrounded by try/catch block)
  2. The catchError path on the actual call (I've added breakpoint here to see when it get executed)
  3. The on DioError catch (dioError) block (I've added breakpoint here to see when it get executed)
    try {
      var httpClient = Dio()..options.contentType = "application/json";

      var response = await httpClient
          .get(
        "https://gorest.co.in/public/v1/posts/nonExistingId",
      )
          .catchError((e) {
        print("Future.catchError: ${e.toString()}");
      });

    } on DioError catch (dioError) {
      print("DioError catch: ${dioError.message}");
    } catch (e) {
      print("Other exception catch: ${e.toString()}");
    }

hmm, I'm not sure how to say this but... it suddenly started working as intended... I was trying to test out older versions of Dio and http_parser and when I reverted to latest versions, there was no more assureDioError exception in the logs and the try/catch caught the error...

I guess there was some cache leftovers? I'm not sure how to explain what happened...

I've used your example to create this test app: https://github.com/markfili/dio_tester
please pull the repo and run the app on an emulator.

first try to get the error by launching a few requests with and without catchError.
then, if it still doesn't work (error not caught in catch block) then try to reproduce what I've done:

  1. in pubspec.yaml set Dio version to 3.0.10 and http_parser to version 2.0.0
  2. use pub get to fetch packages which will fail because they don't support null-safety
  3. remove the http_parser from pubspec.yaml and revert Dio dependency to ^4.0.1
  4. pub get to fetch latest versions
  5. run the app

this is how the External Libraries - Dart packages looks now in my projects:
image

@a7md0
Copy link

a7md0 commented Nov 13, 2021

@markfili Using the repo you provided, as soon as I launched the application I received the same exception

Here is what my breakpoints look like
image

I am actually using the same dio 4.0.1 version, here is my minimal repo. Would you mind sharing your flutter --version and VSCode version?

Visual Studio Code version: 1.62.1 f4af3cbf5a99787542e2a30fe1fd37cd644cc31f x64
Flutter version:

Flutter 2.5.3 • channel stable • https://github.com/flutter/flutter.git  
Framework • revision 18116933e7 (4 weeks ago) • 2021-10-15 10:46:35 -0700
Engine • revision d3ea636dc5
Tools • Dart 2.14.4

@markfili
Copy link

markfili commented Nov 13, 2021

this is how I get the error when running your example app:
image
this means the error is caught in the catch block so I would like to know if we are on the same page, are you getting the same result?

Have you tried the steps I've described in my last reply? Have you tried messing with version numbers, flutter clean and pub get? I know it sounds crazy but it could confirm that I'm not crazy.

I'm running it in Android Studio Arctic Fox - try that, too.

My Flutter Doctor output
ex_unhandled_app git:main ❯ fvm flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.5.1, on macOS 12.0.1 21A559 darwin-x64, locale en-GB)
[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0-rc1)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS
[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✓] Android Studio (version 2020.3)
[✓] IntelliJ IDEA Community Edition (version 2020.1.1)
[✓] VS Code (version 1.62.1)
[✓] Connected device (1 available)

! Doctor found issues in 2 categories.

@a7md0
Copy link

a7md0 commented Nov 13, 2021

I could confirm that I have the same versions as you described. And yes I receive the same output when it get caught in the catch block. But before that occurs, the debugger steps in and pause the execution as following (Only after I click the continue button (F5) my catch block get executed)

image

This might be related to VSCode then, I will try that on Android Studio and post the result. Which also would explain why you were having this issue, but it might been resolved by Android Studio updates

@markfili
Copy link

markfili commented Nov 13, 2021

Ah, this is then another type of issue I was not aware of.
I just tried the debug mode (attaching the debugger) and execution really stops when DioError is thrown from the dio_mixin class.

I was focused on solving the "unable to catch DioError in try/catch" issue when just running the app using the play button (not in IDE's debug mode - without attaching the debugger). The issue there was that the exception was thrown in the logs but never arrived to the catch block, correct?

If you can catch DioError in the catch block but it stops execution when using a debugger then that might be something related to the IDE and debugger settings.

It can probably be evaded by unchecking the "Break on exceptions" in Debugger settings but it might not be the best thing to do as it will do that to all exceptions.

Sure, try and report back so we can reassess the situation and define a new problem if necessary.

@a7md0
Copy link

a7md0 commented Nov 13, 2021

I was focused on solving the "unable to catch DioError in try/catch" issue when just running the app using the play button (not in IDE's debug mode - without attaching the debugger). The issue there was that the exception was thrown in the logs but never arrived to the catch block, correct?

No the issue was that I could not prevent DioError from being thrown, even with the try/catch around the call. It did arrive to the catch block, but only after clicking Continue from the debugger.

If you can catch DioError in the catch block but it stops execution when using a debugger then that might be something related to the IDE and debugger settings.

I agree, this might be related to the IDE debugger. But why it is only triggered with this package?

It can probably be evaded by unchecking the "Break on exceptions" in Debugger settings but it might not be the best thing to do as it will do that to all exceptions.

True, unchecking the Uncaught exception does work. But again this would make the debugger useless

Sure, try and report back so we can reassess the situation and define a new problem if necessary.

I've just tried Android Studio Arctic Fox | 2020.3.1 Patch 3. Same issue persist if I ran the application through the debugger. Starting the application through the run button does not produce the issue

@markfili
Copy link

But why it is only triggered with this package?

I'm not sure, I'm investigating, but...
It does seem to me that you're already on a more direct path to finding an answer to that question
dart-lang/sdk#47692 😉

@markfili
Copy link

markfili commented Nov 13, 2021

flutter/flutter#33427 (comment) This might be an approximate explanation of what's going on
flutter/flutter#33427 (comment) Here's an explanation of the above explanation

@markfili
Copy link

markfili commented Nov 13, 2021

@a7md0 can you please pull my project again and try to reproduce the debugger issue? https://github.com/markfili/dio_tester

edit from tomorrow: I've updated the above project repository with latest Dio 4.0.3

@wendux
Copy link
Contributor

wendux commented Nov 14, 2021

try with 4.0.2

@markfili
Copy link

working!

@a7md0
Copy link

a7md0 commented Nov 15, 2021

Sorry for the late reply. I've tried the version 4.0.2 and it's working perfectly now.

Thanks @markfili & @wendux

@kuhnroyal
Copy link
Member

Looks like this was fixed in 4.0.2

@namanshergill
Copy link

try with 4.0.2

This issue is back in 4.0.6

@dawid-niedzwiecki
Copy link

Issue is back.

@ahmadrasheed
Copy link

back again.

@leopold7
Copy link

leopold7 commented Dec 1, 2022

back again in 4.0.6

@yacineblr
Copy link

Back again in 4.0.6, any news about this ? I use QueuedInterceptorsWrapper

@markfili
Copy link

markfili commented Dec 1, 2022

Does anyone have a(ny) test(s) that could repeatedly confirm this issue?

@MohamedZaton
Copy link

MohamedZaton commented Jan 17, 2023

I have this problem but solve it when I clean cash on Android Studio :

  1. Open Android Studio .
  2. File > invalidate cache/restart.
  3. before run your app you must delete old APK .
  4. finaly flutter run .

@shkvoretz
Copy link

this appears to be back with a new Flutter release 3.16.0. Is anyone experiencing the same issue?

@shakthizen
Copy link

@shkvoretz Yes. I've been looking for a solution for a few days now. Still no luck.

@ranjithbobby89
Copy link

Add interceptor rule in Dio

dio.interceptors.add(InterceptorsWrapper(onError: (DioError e, handler) {
return handler.reject(e);
}));

Now you can get error in catch block. Then we can handle it by internal

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

No branches or pull requests