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

A (caught) exception during web requests pauses the debugger when set to pause on only uncaught exceptions in Dart 3.1 #53334

Closed
DanTup opened this issue Aug 24, 2023 · 56 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends. cherry-pick-candidate Candidates to be cherry-picked P2 A bug or feature request we're likely to work on vm-debugger

Comments

@DanTup
Copy link
Collaborator

DanTup commented Aug 24, 2023

Moved from flutter/flutter#129121. This is a similar issue to #47985, but this on appears to be newly introduced in the latest Dart 3.1 stable release. (I'm testing on Windows - I'm not sure if it's Windows-specific).

Given this code:

import 'package:http/http.dart' as http;

Future<void> main() async {
  try {
    var response = await http.get(Uri.parse('https://www.bbc.co.uk/'));
    print(response.statusCode);
  } catch (e) {
    print(e.toString());
  }
}

In Dart 3.0.7 this code runs without pausing the debugger if set to "pause on uncaught exceptions".

In Dart 3.1.0, the debugger pauses with this exception:

image

image

Logs:

@mraleph remarked on the issue at #47985 (comment) that this may be complicated to fix. It wasn't clear to me at the time that this seems to be newly-introduced in Dart 3.1 and in 3.0.7 did not occur. I thought it may be related to #52487 however that CP existed prior to 3.0.7.

@DanTup DanTup added area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends. vm-debugger labels Aug 24, 2023
@mnordine
Copy link
Contributor

Debugger pauses on host lookup with Dart 3.1 Webstorm on Windows. I have to manually skip through every time, makes debugging very annoying and slow.

@GameTec-live
Copy link

Debugger pauses on host lookup with Dart 3.1 Webstorm on Windows. I have to manually skip through every time, makes debugging very annoying and slow.

yes, it is VERY annoying.
Dart SDK version: 3.1.0 (stable), windows11 pro, vscode

@a-siva
Copy link
Contributor

a-siva commented Aug 24, 2023

We have similar code in
static Future<List<InternetAddress>> lookup(String host....)
which throws the exception
throw createError(response, "Failed host lookup: '$host'");

This code is not new so I don't understand why it is a 3.1 only issue

@a-siva
Copy link
Contributor

a-siva commented Aug 24, 2023

//cc @brianquinlan

@a-siva a-siva added the P2 A bug or feature request we're likely to work on label Aug 24, 2023
@brianquinlan
Copy link
Contributor

brianquinlan commented Aug 24, 2023

This does not seem HTTP-related to me - the debugger should not be pausing for caught exceptions (notice the catch block in the example code) when run in "pause on uncaught exceptions" mode.

@a-siva
Copy link
Contributor

a-siva commented Aug 24, 2023

//cc @derekxu16 @bkonyi did we change something recently in the debugger code around caught/uncaught exceptions ?

@DanTup
Copy link
Collaborator Author

DanTup commented Aug 24, 2023

This code is not new so I don't understand why it is a 3.1 only issue

I also didn't understand that. There were definitely some code changes in this area recently which led to some other issues and a cherry-pick, but that cherry-pick was included in 3.0.7 and I verified multiple times that the issue isn't occurring there.

This does not seem HTTP-related to me

This does not seem HTTP-related to me - the debugger should not be pausing for caught exceptions (notice the catch block in the example code) when run in "pause on uncaught exceptions" mode.

I think there's something specific about this code (or the call stack) that's preventing the VM from determining this exception will be caught. I don't think it's related to package:http, but it's also not just a general issue of the VM incorrectly pausing on all uncaught exceptions.

It's way outside my area of knowledge though so I can't offer much more than that. If I can capture anything more that would help diagnose it (or if this can't be reproduced), let me know!

@mnordine
Copy link
Contributor

I've only hit it for the lookup, so far.

@mraleph
Copy link
Member

mraleph commented Aug 25, 2023

This is most likely related to my change in a52f2b9.

I was thinking that the new implementation should be strictly more precise then the old one, but maybe this precision is what causing the problems here. Let me take a quick look.

In general we can't always expect that in the presence of async code we can connect the place where exception happens to the place which will handle the exception. There are too many manual exception forwarding layers in between.

@mraleph
Copy link
Member

mraleph commented Aug 25, 2023

Yeah, it is definitely related to a52f2b9 - before my change debugger thought that handleValueCallback handled the exception, so it did not pause on it. However handleValueCallback simply converts synchronous exception into asynchronous one. Whether asynchronous one is going to be caught or not depends on where asynchronous exception flows to and in this particular case we fail to fully unwind the stack because the code in staggeredLookup is just too complicated.

@mraleph
Copy link
Member

mraleph commented Aug 25, 2023

I have dusted off a change I have been working on before summer holidays: https://dart-review.googlesource.com/c/sdk/+/322720, it fixes the problem by fixing async unwinding in a way that allows us to get all the way to main from _NativeSocket.lookup. I would need some time to finish this though - as I remember (context completely disappeared from my head).

@tylandercasper
Copy link

Thanks for being on top of this man. I switched from Xamarin because there was a breaking change that still hasn't been fixed a year later, so it's really nice to be using a language that people actually take care of.

@charlieforward9
Copy link

charlieforward9 commented Aug 25, 2023

I second what @tylandercasper said. Its great to follow these along.

If it helps with the fix, I was facing an issue where once the process paused and I pressed 'Restart' the state of the buttons ('Continue', 'Step Over' , ...) to the left of 'Restart' did not reset.

TL;DR when I 'Restart', the 'Continue' and 'Step' buttons were still clickable. (VSCODE)

@DanTup
Copy link
Collaborator Author

DanTup commented Aug 25, 2023

@charlieforward9

TL;DR when I 'Restart', the 'Continue' and 'Step' buttons were still clickable. (VSCODE)

Are you able to reproduce this? Could you file an issue at https://github.com/Dart-Code/Dart-Code with steps. I don't think it's related to this issue, but I'd like to take a look. Thanks!

@PriyanshuMallick
Copy link

Is there a way to add the ability to suppress certain exceptions? Like, mute them so that they don't pause the debugger? If not, can we add it as a temporary fix with the additional ability to just log them so that we still know that was some exception that had occurred during debugging just mute/ignore them completely?

@mraleph
Copy link
Member

mraleph commented Aug 29, 2023

Is there a way to add the ability to suppress certain exceptions?

Yeah, I was going to suggest the same. @DanTup is it possible to make a change to VSCode plugin to simply suppress this particular exception from stopping the debugger altogether for now?

@DanTup
Copy link
Collaborator Author

DanTup commented Aug 29, 2023

@mraleph

@DanTup is it possible to make a change to VSCode plugin to simply suppress this particular exception from stopping the debugger altogether for now?

I'm not sure we could do this reliably from VS Code itself. The debug adapter now lives inside the SDK so the natural place to do this would require an SDK release/hotfix.

It might be possible to do it via some middleware in VS Code (sniffing the DAP messages and issuing a resume) but I feel like it could be quite risky/error-prone since there's not enough information in a DAP pause event to know we'd want to resume, we'd have to issue additional DAP requests to get stack and exception information to determine this.

@jacob314 @bkonyi thoughts on this? If we need to do something, I feel like handling it in DAP would be much better(/more reliable), but releasing it (SDK + DDS hotfixes) would be more involved.

@mnordine
Copy link
Contributor

Coming from a company where some programmers use WebStorm, I would hope it would be fixed there, too.

@Jimleskog
Copy link

Some newbi input in this matter. As I also get this annoying breakpoint Exception in Uncaught settings.

What I noticed is that the http request does not give the exception for maps.google.com

and it dos give for for location-to-address.p.rapidapi.com

When I ping maps.google.com it gives the ping back

but not on location-to-address.p.rapidapi.com

Pinging location-to-address.p.rapidapi.com [3.124.111.61] with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.

Ping statistics for 3.124.111.61:
Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

Pinging maps.google.com [142.250.74.110] with 32 bytes of data:

Reply from 142.250.74.110: bytes=32 time=34ms TTL=56
Reply from 142.250.74.110: bytes=32 time=27ms TTL=56
Reply from 142.250.74.110: bytes=32 time=25ms TTL=56
Reply from 142.250.74.110: bytes=32 time=26ms TTL=56

Ping statistics for 142.250.74.110:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 25ms, Maximum = 34ms, Average = 28ms

So maybe this lookup function uses a similiar tactic to check for host and then throws an error wich can't be caught through all the layers.

@aam
Copy link
Contributor

aam commented Sep 5, 2023

@a-siva is there a cherry-pick request or change open for this in the stable branch? I couldn't find one but it'd be useful for me to know when it lands so I can respond to reports of this issue appropriately. Thanks!

Not yet. https://dart-review.googlesource.com/c/sdk/+/323684 once it lands is what expected to be cherry-picked into stable.

copybara-service bot pushed a commit that referenced this issue Sep 6, 2023
Applying patch from @aam for using try/catch in lookupAddresses instead
of Future error.

This will be cherry picked into the stable branch to ensure we
address the expedient issue in #53334

TEST=new test added.

Change-Id: Ia5375cbd118d8d6437cf6869383f173cab48aa3f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/323684
Commit-Queue: Siva Annamalai <asiva@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
@a-siva
Copy link
Contributor

a-siva commented Sep 6, 2023

#53450

@theSonGoku1991
Copy link

I just switched to the main branch and updated to the latest release. I am still facing the "No address associated with hostname" issue when trying to use Image.network though.

Interestingly, when I use

await InternetAddress.lookup('google.de').then((value){ print(value); });

that prints me the IPv4 and the IPv6 adress.

Or did I do something wrong and am just a noob? :D

copybara-service bot pushed a commit that referenced this issue Sep 11, 2023
Applying patch from @aam for using try/catch in lookupAddresses instead
of Future error.

This cherry pick into the stable branch is to ensure we
address the expedient issue in #53334

TEST=new test added.

Bug: #53334
Change-Id: Ia5375cbd118d8d6437cf6869383f173cab48aa3f
Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/323684
Cherry-pick-request: #53450
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/324569
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
@galvin59
Copy link

Hi
I am quite new to git (sorry for that :))
And very annoyed by this bug, that makes my app almost impossible to debug.
I saw there is a cherry pick (discovered that cute expression too) that was made, but stupid question : how to apply it on my local machine ?
I tried through fvm with "fvm use a0c2791" but I am getting an error
Any help will be greatly appreciated and sorry again for this noob question 🙄

@DanTup
Copy link
Collaborator Author

DanTup commented Sep 12, 2023

I tried through fvm with "fvm use a0c2791" but I am getting an error

I'm not familiar with fvm, but that commit fix is a Dart (not Flutter) SDK commit. On its own, that change only gets the fix into dart. There are some additional steps for that Dart SDK to get into Flutter (although I'm not familiar with what the exact steps).

@brianquinlan
Copy link
Contributor

The next hotfix releases of Dart and Flutter should happen tomorrow (fingers crossed) and will fix this issue. Thanks for your patience everyone!

@tksoh
Copy link

tksoh commented Sep 13, 2023

Just a minor thing. I noticed the changelog for Dart 3.1.2 is not pointing to this issue correctly (link is pointing to issue 53450 instead). Perhaps someone can fix the typo to avoid further confusion.

@vadrian89
Copy link

The next hotfix releases of Dart and Flutter should happen tomorrow (fingers crossed) and will fix this issue. Thanks for your patience everyone!

It fixed the issue for me. Many thanks to all involved!

@thumbert
Copy link

Unfortunately, even with the latest version below I get the same error. I can't debug anything that requires data from an external server inside a unit test. It's an extremely painful experience! I'm using IntelliJ but if this issue is fixed on VSCode, I'm willing to switch editors just to get debugging back.

$ flutter --version
Flutter 3.13.9 • channel stable • https://github.com/flutter/flutter.git
Framework • revision d211f42860 (5 days ago) • 2023-10-25 13:42:25 -0700
Engine • revision 0545f8705d
Tools • Dart 3.1.5 • DevTools 2.25.0

My experience is that the code will not throw if placed in main, but throws an exception if it is inside a flutter unit test. A simple http GET does it for me. I don't want to downgrade flutter.

@DanTup
Copy link
Collaborator Author

DanTup commented Oct 30, 2023

@thumbert I'd suggest filing a new issue with a code sample that triggers this. The fix here was for a very specific exception/path so it's possible you're seeing something different.

You might see slightly different behaviour between VS Code and IntelliJ because I don't think IntelliJ has the same options as VS Code (in VS Code you can choose different pause behaviour for your own code vs SDK/Pub packages), however I don't think the fix made here should appear differently between editors.

@thumbert
Copy link

thumbert commented Oct 31, 2023

@DanTup Thanks. I've submitted flutter/flutter#137629. I think I've narrowed the conditions down a bit more.

copybara-service bot pushed a commit that referenced this issue Feb 15, 2024
This CL adds @pragma('vm:awaiter-link') in various places in
Stream implementation to facilitate unwinding and expands
async unwinding logic with more information about
Stream internals.

At the same time be more conservative when checking if an
exception thrown from async method handled: failing to unwind
the stack fully creates situations when we incorrectly report
caught exceptions as uncaught, which frustrates users.

To distinguish stream subscriptions with and without error
handlers we add a state bit. Otherwise, it looks like all
subscriptions have error handlers because if no error
handler is installed we eagerly install error handler forwarding
the error to `Zone.handleUncaughtError`.

Fixes #53334
Fixes #54788
Fixes #47985

TEST=runtime/vm/dart/awaiter_stacks/stream_methods_test.dart,pkg/vm_service/test/pause_on_unhandled_async_exceptions6_test.dart,pkg/vm_service/test/pause_on_unhandled_async_exceptions7_test.dart

CoreLibraryReviewExempt: No behavioral change. Async changes reviewed by lrhn@
Cq-Include-Trybots: luci.dart.try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-dwarf-linux-product-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try
Change-Id: Ic51f926867092dd0adbe801b753f57c357c7ace2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/322720
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
@lukehutch
Copy link

@DanTup @darshankawar

I'm still getting sporadic failures of http.get on Flutter 3.19.0-0.4.pre / Dart 3.3.0-279.3.beta, on the Android emulator, while running from VS Code:

[log] _ClientSocketException (ClientException with SocketException: Failed host lookup: '[ELIDED]' (OS Error: No address associated with hostname, errno = 7), uri=[ELIDED])
[log] #0      IOClient.send (package:http/src/io_client.dart:154:7)
      <asynchronous suspension>
      #1      BaseClient._sendUnstreamed (package:http/src/base_client.dart:93:32)
      <asynchronous suspension>
      #2      _withClient (package:http/http.dart:167:12)
      <asynchronous suspension>

(The AndroidManifest.xml file does include the INTERNET permission).

@DanTup
Copy link
Collaborator Author

DanTup commented Feb 20, 2024

@lukehutch there's a commit that references this issue above made 5 days ago by @mraleph. I suspect that change is not in the beta channel. I would try on the master channel and if the issue reproduces there, open a new issue with a code sample that triggers the issue. Thanks!

@mraleph
Copy link
Member

mraleph commented Feb 20, 2024

Note that I have not changed anything with respect to how exceptions are reported. Only interactions with debugger were adjusted. If exception is reaching your log - it is probably genuinely uncaught and this has nothing to do with my changes.

@DanTup
Copy link
Collaborator Author

DanTup commented Feb 20, 2024

Oh yeah, I overlooked that this was logged and not just showing in the debugger. A code sample to repro would definitely help.

@lukehutch
Copy link

lukehutch commented Feb 20, 2024

@DanTup the reproducer is very simple: (@mraleph the following code is in fact surrounded with a try/catch, so I am catching the exception in my code, but the exception is still printed by the server)

  final lat = 37.422510;
  final lng = -122.084135;
  try {
    final uri =
        Uri.parse('https://api.bigdatacloud.net/data/reverse-geocode-client?latitude=$lat&longitude=$lng');
    final response = await http.get(uri);
    print('Response status: ${response.statusCode}');
    print('Response body: ${response.body}');
  } catch (e) {
    print('Request failed: $e');
  }

This is run from within a Flutter UI, in the Android emulator.

From what I can determine from other similar bug reports, this is triggered when either the client or the server does not support IPv6. If that's true, then since this issue happens only sporadically, I assume that bigdatacloud.net is load-balanced, and at least one of the servers is improperly configured (or not configured) for IPv6.

@DanTup
Copy link
Collaborator Author

DanTup commented Feb 20, 2024

@lukehutch are you using something like dio with a LogInterceptor by any chance?

If not, can you provide a complete runnable sample that reproduces the issue (please file in a new issue so we can avoid pinging everyone that commented above). I tried your code sample in a simple project that just uses package:http and that code, but it's behaving as I'd expect (both when successful, and if I disable WiFi to force a DNS failure).

@lukehutch
Copy link

@DanTup I tried reproducing this in a standalone project, but I can't trigger the problem, so I won't create a new issue for now. No, I'm not using dio, just raw http in my much larger project.

@mraleph
Copy link
Member

mraleph commented Feb 21, 2024

@lukehutch I would suggest to review your code to see if you have any places where you invoke http.get (or similar method) without actually awaiting it. You can see that reported stack trace stops at _withClient - this means the call site is not using await.

@a-siva
Copy link
Contributor

a-siva commented Apr 1, 2024

@cetindogu there has been a lot of discussion on this issue with some changes that have already landed, which problem are you asking about ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends. cherry-pick-candidate Candidates to be cherry-picked P2 A bug or feature request we're likely to work on vm-debugger
Projects
None yet
Development

No branches or pull requests