You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Debugger pauses on exception that will be caught #2063
@zichangg any thoughts on this? It sounds a bit like dart-lang/sdk#37645, however in this code it seems like the VM should be able to tell this exception will be caught (there's a catch block at the same level and the future is awaited). The settings are set to only break on uncaught exceptions (seen in the bottom left).
From the screen shot, I didn't see anything goes wrong.
The debugger has paused on the exception, but it's set to only pause on uncaught exceptions (shown in the tickboxes in the bottom left of the screenshot).
I suspect that the exception is the first one showed in dart-lang/sdk#37645 (comment). Because in VScode, libraries are non-debuggable so it doesn't show at where it happens. Instead, it marked line in your _auth(). You can look at comments on #37645.
@Fordevind Can you check whether 'debugSdkLibraries' and 'debugExternalLibraries' are set to 'false' in your setting?
An unhandled exception was thrown inside libraries. Since 'debugSdkLibraries' and 'debugExternalLibraries' are 'false'. It didn't pause until program reaches the user written code.
Here is what @DanTup explained in the other thread.
it would only break once the exception made it up to the user code. This is somewhat what we achieve in VS Code today by automatically jumping up the call stack to the users code
Why exception is considered as 'unhandled' even if you put 'try catch' block?
VM determines whether an exception is handled or not by checking current stack trace. But when thing happens asynchronously, stack may be out of date and not contains frame that has handler.
@zichangg I'm not sure I understand. At the location where the debugger is breaking, isn't the try/catch visible in the stack? This seems very confusing to users (it keeps coming up - another one at #2085 this weekend), is there anything that can be done?
We default to having SDK libraries as non-debuggable as most users seem to prefer to treat the SDK as a black box and not have to keep stepping in/out of it (we used to have those settings enabled by default, but when we added an option we prompted users, and almost all picked to debug "just my code" so that became the new default).
At the location where the debugger is breaking, isn't the try/catch visible in the stack?
It is visible. But it is not the same as the stack when exception is thrown.
I suspect that when exception was thrown inside the external library, the stack doesn't contain handler frame. So VM treat it as unhandled.
Due to 'non-debuggable libraries',correct me if I'm wrong, VScode resumes pausing until it reaches user-written code. The stack changes as exception propagates. It ends up pausing on a different place and displaying current stack(not the stack when exception is thrown).
Due to 'non-debuggable libraries',correct me if I'm wrong, VScode resumes pausing until it reaches user-written code.
Sorry, my previous comment was a little misleading. The VM is still breaking in the location of the exception, but VS Code is choosing to display the first stack frame of user code (if you look at the call stack, you'll see it still goes all the way up to where the exception is thrown - that is where the VM is paused).
So if we were to ignore the VS Code behaviour of jumping up the stack (this is only cosmetic, to put the user at their own code - we're not telling the VM to do anything) then we are essentially paused at the location of the original exception.
So I think this may be the same thing described at the end of the comment here:
In this case, the exception is considered unhandled and the debugger breaks (the timeout did not trigger - the exception occurred immediately, though presumably will have been passed through the timeout function).
If I delete .timeout(Duration(seconds: 100)) from the end, then the debugger does not break.
I think this is the implementation of the timeout:
It uses a class called _Future which seems to work a little like Completer, however when I tried to reproduce the issue using a Complete that completes with an error, I could not.
The VM is still breaking in the location of the exception, but VS Code is choosing to display the first stack frame of user code (if you look at the call stack, you'll see it still goes all the way up to where the exception is thrown - that is where the VM is paused).
Get it!
I run the sample with "--trace-debugger-stacktrace". This is likely to be a bug in debugger. Stack trace was truncated.
CollectAwaiterReturnStackTrace: visiting frame:
[dart : sp(0x7fa1bfdfd2f8) fp(0x7fa1bfdfd3a0) pc(0x7fa1c02fc745) package:http/src/io_client.dart_IOClient_send__async_op ]
Found saved current ctx at index -5
Using saved context: Context num_variables: 3 parent:{ Context num_variables: 12 }
Line number: 33
CollectAwaiterReturnStackTrace: visiting frame:
[dart : sp(0x7fa1bfdfd3b0) fp(0x7fa1bfdfd3f0) pc(0x7fa1bd722c40) dart:core__Closure@0150898_call ]
Found saved current ctx at index 0
Using saved context: Context: null
Line number: -1
I don't think it was specific to .timeout(), I think it was related to the function taking a future, but then using a completer to products its own future that succeeds/fails. I think the initial future throwing was considered unhandled, even though the only place waiting on its result was handling it.
@zichangg likely understands this better though (I'm not sure whether the original issue was resolved or not).
Activity
DanTup commentedon Oct 22, 2019
@zichangg any thoughts on this? It sounds a bit like dart-lang/sdk#37645, however in this code it seems like the VM should be able to tell this exception will be caught (there's a catch block at the same level and the future is
awaited). The settings are set to only break on uncaught exceptions (seen in the bottom left).[-]VS Code doesn't catched SocketException[/-][+]Debugger pauses on exception that will be caught[/+]zichangg commentedon Oct 22, 2019
From the screen shot, I didn't see anything goes wrong. The stack is not truncated from the screen shot. So that should be an caught exception.
@Fordevind Can you do a
dart --version? Is this a regression or new issue? It will be great if you have a reproduction instruction.Fordevind commentedon Oct 23, 2019
@zichangg
Dart VM version: 2.5.0 (Fri Sep 6 20:10:36 2019 +0200) on "windows_x64"Issue appeared after upgrade from Flutter 1.5.4 to 1.9.1.
Steps to reproduce:
DanTup commentedon Oct 23, 2019
The debugger has paused on the exception, but it's set to only pause on uncaught exceptions (shown in the tickboxes in the bottom left of the screenshot).
zichangg commentedon Oct 23, 2019
Thanks! I'll take a look later.
Well, what I mean is code itself looks right. ^_^
zichangg commentedon Oct 23, 2019
@DanTup Can you assign me this issue, if possible? I need to finish some other issues first.
DanTup commentedon Oct 23, 2019
Oh, I see! 😄
Apparently I can! I thought I'd have to add you to the repo first, but apparently not :-)
zichangg commentedon Nov 1, 2019
I suspect that the exception is the first one showed in dart-lang/sdk#37645 (comment). Because in VScode, libraries are non-debuggable so it doesn't show at where it happens. Instead, it marked line in your _auth(). You can look at comments on #37645.
@Fordevind Can you check whether 'debugSdkLibraries' and 'debugExternalLibraries' are set to 'false' in your setting?
Fordevind commentedon Nov 1, 2019
@zichangg It was set to 'false'

zichangg commentedon Nov 1, 2019
Thanks!
An unhandled exception was thrown inside libraries. Since 'debugSdkLibraries' and 'debugExternalLibraries' are 'false'. It didn't pause until program reaches the user written code.
Here is what @DanTup explained in the other thread.
Why exception is considered as 'unhandled' even if you put 'try catch' block?
VM determines whether an exception is handled or not by checking current stack trace. But when thing happens asynchronously, stack may be out of date and not contains frame that has handler.
DanTup commentedon Nov 4, 2019
@zichangg I'm not sure I understand. At the location where the debugger is breaking, isn't the try/catch visible in the stack? This seems very confusing to users (it keeps coming up - another one at #2085 this weekend), is there anything that can be done?
We default to having SDK libraries as non-debuggable as most users seem to prefer to treat the SDK as a black box and not have to keep stepping in/out of it (we used to have those settings enabled by default, but when we added an option we prompted users, and almost all picked to debug "just my code" so that became the new default).
zichangg commentedon Nov 4, 2019
It is visible. But it is not the same as the stack when exception is thrown.
I suspect that when exception was thrown inside the external library, the stack doesn't contain handler frame. So VM treat it as unhandled.
Due to 'non-debuggable libraries',correct me if I'm wrong, VScode resumes pausing until it reaches user-written code. The stack changes as exception propagates. It ends up pausing on a different place and displaying current stack(not the stack when exception is thrown).
DanTup commentedon Nov 5, 2019
Sorry, my previous comment was a little misleading. The VM is still breaking in the location of the exception, but VS Code is choosing to display the first stack frame of user code (if you look at the call stack, you'll see it still goes all the way up to where the exception is thrown - that is where the VM is paused).
So if we were to ignore the VS Code behaviour of jumping up the stack (this is only cosmetic, to put the user at their own code - we're not telling the VM to do anything) then we are essentially paused at the location of the original exception.
So I think this may be the same thing described at the end of the comment here:
dart-lang/sdk#37645 (comment)
which was that the SDK/libraries are using
.catchError()and nottry/catchthemselves?I'll try and do some more testing of this later today and see exactly where the exception occurs and what the stack looks like.
DanTup commentedon Nov 5, 2019
Ok, seems like this is actually being trigged by having
.timeout()on the end (even if the timeout does not fire).I can repro with this code:
In this case, the exception is considered unhandled and the debugger breaks (the timeout did not trigger - the exception occurred immediately, though presumably will have been passed through the timeout function).
If I delete
.timeout(Duration(seconds: 100))from the end, then the debugger does not break.I think this is the implementation of the timeout:
https://github.com/dart-lang/sdk/blob/4ebc1e3fe7e1cd3d000ec2c371671a51149a3a5c/sdk/lib/async/future_impl.dart#L753
It uses a class called
_Futurewhich seems to work a little likeCompleter, however when I tried to reproduce the issue using aCompletethat completes with an error, I could not.@zichangg does this make any sense to you?
zichangg commentedon Nov 8, 2019
Sorry for the late reply.
Get it!
I run the sample with "--trace-debugger-stacktrace". This is likely to be a bug in debugger. Stack trace was truncated.
Stack(from top to bot):
CollectAwaiterReturnStackTrace: visiting frame:
[exit : sp(0) fp(0x7fa1bfdfd2e8) pc(0)]
CollectAwaiterReturnStackTrace: visiting frame:
[dart : sp(0x7fa1bfdfd2f8) fp(0x7fa1bfdfd3a0) pc(0x7fa1c02fc745) package:http/src/io_client.dart_IOClient_send__async_op ]
Found saved current ctx at index -5
Using saved context: Context num_variables: 3 parent:{ Context num_variables: 12 }
Line number: 33
CollectAwaiterReturnStackTrace: visiting frame:
[dart : sp(0x7fa1bfdfd3b0) fp(0x7fa1bfdfd3f0) pc(0x7fa1bd722c40) dart:core__Closure@0150898_call ]
Found saved current ctx at index 0
Using saved context: Context: null
Line number: -1
CollectAwaiterReturnStackTrace: visiting frame:
[dart : sp(0x7fa1bfdfd400) fp(0x7fa1bfdfd450) pc(0x7fa1bd60a280) dart:async_::_asyncErrorWrapperHelper@9048458 ]
CollectAwaiterReturnStackTrace: visiting awaiter return closures:
package:http/src/base_client.dart_BaseClient__sendUnstreamed@23340606__async_op
CollectAwaiterReturnStackTrace: visiting awaiter return closures:
package:http/http.dart_::__withClient@20447473__async_op
It doesn't contain frame that has user-written try catch block.
I have other prioritized issue to work on, so I'll get back to this later.
DanTup commentedon Nov 11, 2019
Ok, great - let me know if you need anything more info or someone to test a fix :-)
HerrNiklasRaab commentedon Apr 26, 2020
Is this issue specific to
.timeoutor general?Just wondering because I am also getting something similiar:

DanTup commentedon Apr 27, 2020
I don't think it was specific to
.timeout(), I think it was related to the function taking a future, but then using a completer to products its own future that succeeds/fails. I think the initial future throwing was considered unhandled, even though the only place waiting on its result was handling it.@zichangg likely understands this better though (I'm not sure whether the original issue was resolved or not).
DanTup commentedon Jan 12, 2021
Closing this as a dupe of dart-lang/sdk#37953, since the fix will need to be done there (and would apply automatically in VS Code).