Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
2a8dba4a
Unverified
Commit
2a8dba4a
authored
Apr 15, 2021
by
Michael Goderbauer
Committed by
GitHub
Apr 15, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Treat some exceptions as unhandled when a debugger is attached (#78649)
parent
eb735167
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
833 additions
and
5 deletions
+833
-5
listener_helpers.dart
packages/flutter/lib/src/animation/listener_helpers.dart
+2
-0
assertions.dart
packages/flutter/lib/src/foundation/assertions.dart
+27
-3
change_notifier.dart
packages/flutter/lib/src/foundation/change_notifier.dart
+1
-0
binding.dart
packages/flutter/lib/src/gestures/binding.dart
+1
-0
pointer_router.dart
packages/flutter/lib/src/gestures/pointer_router.dart
+1
-0
pointer_signal_resolver.dart
...ges/flutter/lib/src/gestures/pointer_signal_resolver.dart
+1
-1
recognizer.dart
packages/flutter/lib/src/gestures/recognizer.dart
+1
-0
image_stream.dart
packages/flutter/lib/src/painting/image_stream.dart
+2
-0
object.dart
packages/flutter/lib/src/rendering/object.dart
+2
-0
binding.dart
packages/flutter/lib/src/scheduler/binding.dart
+6
-0
binding.dart
packages/flutter/lib/src/services/binding.dart
+4
-0
actions.dart
packages/flutter/lib/src/widgets/actions.dart
+1
-0
binding.dart
packages/flutter/lib/src/widgets/binding.dart
+1
-0
editable_text.dart
packages/flutter/lib/src/widgets/editable_text.dart
+3
-0
focus_manager.dart
packages/flutter/lib/src/widgets/focus_manager.dart
+1
-0
framework.dart
packages/flutter/lib/src/widgets/framework.dart
+6
-0
layout_builder.dart
packages/flutter/lib/src/widgets/layout_builder.dart
+4
-0
router.dart
packages/flutter/lib/src/widgets/router.dart
+2
-1
sliver.dart
packages/flutter/lib/src/widgets/sliver.dart
+1
-0
break_on_framework_exceptions_test.dart
...integration.shard/break_on_framework_exceptions_test.dart
+766
-0
No files found.
packages/flutter/lib/src/animation/listener_helpers.dart
View file @
2a8dba4a
...
...
@@ -135,6 +135,7 @@ mixin AnimationLocalListenersMixin {
/// If listeners are added or removed during this function, the modifications
/// will not change which listeners are called during this iteration.
@protected
@pragma
(
'vm:notify-debugger-on-exception'
)
void
notifyListeners
()
{
final
List
<
VoidCallback
>
localListeners
=
List
<
VoidCallback
>.
from
(
_listeners
);
for
(
final
VoidCallback
listener
in
localListeners
)
{
...
...
@@ -223,6 +224,7 @@ mixin AnimationLocalStatusListenersMixin {
/// If listeners are added or removed during this function, the modifications
/// will not change which listeners are called during this iteration.
@protected
@pragma
(
'vm:notify-debugger-on-exception'
)
void
notifyStatusListeners
(
AnimationStatus
status
)
{
final
List
<
AnimationStatusListener
>
localListeners
=
List
<
AnimationStatusListener
>.
from
(
_statusListeners
);
for
(
final
AnimationStatusListener
listener
in
localListeners
)
{
...
...
packages/flutter/lib/src/foundation/assertions.dart
View file @
2a8dba4a
...
...
@@ -15,6 +15,7 @@ import 'stack_frame.dart';
// late bool draconisAlive;
// late bool draconisAmulet;
// late Diagnosticable draconis;
// void methodThatMayThrow() { }
/// Signature for [FlutterError.onError] handler.
typedef
FlutterExceptionHandler
=
void
Function
(
FlutterErrorDetails
details
);
...
...
@@ -876,9 +877,7 @@ class FlutterError extends Error with DiagnosticableTreeMixin implements Asserti
///
/// Do not call [onError] directly, instead, call [reportError], which
/// forwards to [onError] if it is not null.
static
FlutterExceptionHandler
?
onError
=
_defaultErrorHandler
;
static
void
_defaultErrorHandler
(
FlutterErrorDetails
details
)
=>
presentError
(
details
);
static
FlutterExceptionHandler
?
onError
=
presentError
;
/// Called by the Flutter framework before attempting to parse a [StackTrace].
///
...
...
@@ -1101,6 +1100,31 @@ class FlutterError extends Error with DiagnosticableTreeMixin implements Asserti
}
/// Calls [onError] with the given details, unless it is null.
///
/// {@tool snippet}
/// When calling this from a `catch` block consider annotating the method
/// containing the `catch` block with
/// `@pragma('vm:notify-debugger-on-exception')` to allow an attached debugger
/// to treat the exception as unhandled. This means instead of executing the
/// `catch` block, the debugger can break at the original source location from
/// which the exception was thrown.
///
/// ```dart
/// @pragma('vm:notify-debugger-on-exception')
/// void doSomething() {
/// try {
/// methodThatMayThrow();
/// } catch (exception, stack) {
/// FlutterError.reportError(FlutterErrorDetails(
/// exception: exception,
/// stack: stack,
/// library: 'example library',
/// context: ErrorDescription('while doing something'),
/// ));
/// }
/// }
/// ```
/// {@end-tool}
static
void
reportError
(
FlutterErrorDetails
details
)
{
assert
(
details
!=
null
);
assert
(
details
.
exception
!=
null
);
...
...
packages/flutter/lib/src/foundation/change_notifier.dart
View file @
2a8dba4a
...
...
@@ -283,6 +283,7 @@ class ChangeNotifier implements Listenable {
/// See the discussion at [removeListener].
@protected
@visibleForTesting
@pragma
(
'vm:notify-debugger-on-exception'
)
void
notifyListeners
()
{
assert
(
_debugAssertNotDisposed
());
if
(
_count
==
0
)
...
...
packages/flutter/lib/src/gestures/binding.dart
View file @
2a8dba4a
...
...
@@ -390,6 +390,7 @@ mixin GestureBinding on BindingBase implements HitTestable, HitTestDispatcher, H
/// The `hitTestResult` argument may only be null for [PointerAddedEvent]s or
/// [PointerRemovedEvent]s.
@override
// from HitTestDispatcher
@pragma
(
'vm:notify-debugger-on-exception'
)
void
dispatchEvent
(
PointerEvent
event
,
HitTestResult
?
hitTestResult
)
{
assert
(!
locked
);
// No hit test information implies that this is a [PointerHoverEvent],
...
...
packages/flutter/lib/src/gestures/pointer_router.dart
View file @
2a8dba4a
...
...
@@ -87,6 +87,7 @@ class PointerRouter {
throw
UnsupportedError
(
'debugGlobalRouteCount is not supported in release builds'
);
}
@pragma
(
'vm:notify-debugger-on-exception'
)
void
_dispatch
(
PointerEvent
event
,
PointerRoute
route
,
Matrix4
?
transform
)
{
try
{
event
=
event
.
transformed
(
transform
);
...
...
packages/flutter/lib/src/gestures/pointer_signal_resolver.dart
View file @
2a8dba4a
...
...
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/foundation.dart'
;
import
'events.dart'
;
...
...
@@ -189,6 +188,7 @@ class PointerSignalResolver {
///
/// This is called by the [GestureBinding] after the framework has finished
/// dispatching the pointer signal event.
@pragma
(
'vm:notify-debugger-on-exception'
)
void
resolve
(
PointerSignalEvent
event
)
{
if
(
_firstRegisteredCallback
==
null
)
{
assert
(
_currentEvent
==
null
);
...
...
packages/flutter/lib/src/gestures/recognizer.dart
View file @
2a8dba4a
...
...
@@ -165,6 +165,7 @@ abstract class GestureRecognizer extends GestureArenaMember with DiagnosticableT
/// callback that returns a string describing useful debugging information,
/// e.g. the arguments passed to the callback.
@protected
@pragma
(
'vm:notify-debugger-on-exception'
)
T
?
invokeCallback
<
T
>(
String
name
,
RecognizerCallback
<
T
>
callback
,
{
String
Function
()?
debugReport
})
{
assert
(
callback
!=
null
);
T
?
result
;
...
...
packages/flutter/lib/src/painting/image_stream.dart
View file @
2a8dba4a
...
...
@@ -614,6 +614,7 @@ abstract class ImageStreamCompleter with Diagnosticable {
/// Calls all the registered listeners to notify them of a new image.
@protected
@pragma
(
'vm:notify-debugger-on-exception'
)
void
setImage
(
ImageInfo
image
)
{
_checkDisposed
();
_currentImage
?.
dispose
();
...
...
@@ -668,6 +669,7 @@ abstract class ImageStreamCompleter with Diagnosticable {
///
/// See [FlutterErrorDetails] for further details on these values.
@protected
@pragma
(
'vm:notify-debugger-on-exception'
)
void
reportError
({
DiagnosticsNode
?
context
,
required
Object
exception
,
...
...
packages/flutter/lib/src/rendering/object.dart
View file @
2a8dba4a
...
...
@@ -1617,6 +1617,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
owner
!.
_nodesNeedingLayout
.
add
(
this
);
}
@pragma
(
'vm:notify-debugger-on-exception'
)
void
_layoutWithoutResize
()
{
assert
(
_relayoutBoundary
==
this
);
RenderObject
?
debugPreviousActiveLayout
;
...
...
@@ -1671,6 +1672,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
/// children unconditionally. It is the [layout] method's responsibility (as
/// implemented here) to return early if the child does not need to do any
/// work to update its layout information.
@pragma
(
'vm:notify-debugger-on-exception'
)
void
layout
(
Constraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
if
(!
kReleaseMode
&&
debugProfileLayoutsEnabled
)
Timeline
.
startSync
(
'
$runtimeType
'
,
arguments:
timelineArgumentsIndicatingLandmarkEvent
);
...
...
packages/flutter/lib/src/scheduler/binding.dart
View file @
2a8dba4a
...
...
@@ -280,6 +280,7 @@ mixin SchedulerBinding on BindingBase {
}
}
@pragma
(
'vm:notify-debugger-on-exception'
)
void
_executeTimingsCallbacks
(
List
<
FrameTiming
>
timings
)
{
final
List
<
TimingsCallback
>
clonedCallbacks
=
List
<
TimingsCallback
>.
from
(
_timingsCallbacks
);
...
...
@@ -450,6 +451,10 @@ mixin SchedulerBinding on BindingBase {
///
/// Also returns false if there are no tasks remaining.
@visibleForTesting
// TODO(goderbauer): Add pragma (and enable test in
// break_on_framework_exceptions_test.dart) once debugger breaks on correct
// line, https://github.com/dart-lang/sdk/issues/45684
// @pragma('vm:notify-debugger-on-exception')
bool
handleEventLoopCallback
()
{
if
(
_taskQueue
.
isEmpty
||
locked
)
return
false
;
...
...
@@ -1133,6 +1138,7 @@ mixin SchedulerBinding on BindingBase {
// Wraps the callback in a try/catch and forwards any error to
// [debugSchedulerExceptionHandler], if set. If not set, then simply prints
// the error.
@pragma
(
'vm:notify-debugger-on-exception'
)
void
_invokeFrameCallback
(
FrameCallback
callback
,
Duration
timeStamp
,
[
StackTrace
?
callbackStack
])
{
assert
(
callback
!=
null
);
assert
(
_FrameCallbackEntry
.
debugCurrentCallbackStack
==
null
);
...
...
packages/flutter/lib/src/services/binding.dart
View file @
2a8dba4a
...
...
@@ -272,6 +272,10 @@ class _DefaultBinaryMessenger extends BinaryMessenger {
}
@override
// TODO(goderbauer): Add pragma (and enable test in
// break_on_framework_exceptions_test.dart) when it works on async methods,
// https://github.com/dart-lang/sdk/issues/45673
// @pragma('vm:notify-debugger-on-exception')
Future
<
void
>
handlePlatformMessage
(
String
channel
,
ByteData
?
data
,
...
...
packages/flutter/lib/src/widgets/actions.dart
View file @
2a8dba4a
...
...
@@ -198,6 +198,7 @@ abstract class Action<T extends Intent> with Diagnosticable {
/// See the discussion at [removeActionListener].
@protected
@visibleForTesting
@pragma
(
'vm:notify-debugger-on-exception'
)
void
notifyActionListeners
()
{
if
(
_listeners
.
isEmpty
)
{
return
;
...
...
packages/flutter/lib/src/widgets/binding.dart
View file @
2a8dba4a
...
...
@@ -1187,6 +1187,7 @@ class RenderObjectToWidgetElement<T extends RenderObject> extends RootRenderObje
assert
(
_newWidget
==
null
);
}
@pragma
(
'vm:notify-debugger-on-exception'
)
void
_rebuild
()
{
try
{
_child
=
updateChild
(
_child
,
widget
.
child
,
_rootChildSlot
);
...
...
packages/flutter/lib/src/widgets/editable_text.dart
View file @
2a8dba4a
...
...
@@ -1873,6 +1873,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
}
}
@pragma
(
'vm:notify-debugger-on-exception'
)
void
_finalizeEditing
(
TextInputAction
action
,
{
required
bool
shouldUnfocus
})
{
// Take any actions necessary now that the user has completed editing.
if
(
widget
.
onEditingComplete
!=
null
)
{
...
...
@@ -2126,6 +2127,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
}
}
@pragma
(
'vm:notify-debugger-on-exception'
)
void
_handleSelectionChanged
(
TextSelection
selection
,
SelectionChangedCause
?
cause
)
{
// We return early if the selection is not valid. This can happen when the
// text of [EditableText] is updated at the same time as the selection is
...
...
@@ -2259,6 +2261,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
_lastBottomViewInset
=
WidgetsBinding
.
instance
!.
window
.
viewInsets
.
bottom
;
}
@pragma
(
'vm:notify-debugger-on-exception'
)
void
_formatAndSetValue
(
TextEditingValue
value
,
SelectionChangedCause
?
cause
,
{
bool
userInteraction
=
false
})
{
// Only apply input formatters if the text has changed (including uncommited
// text in the composing region), or when the user committed the composing
...
...
packages/flutter/lib/src/widgets/focus_manager.dart
View file @
2a8dba4a
...
...
@@ -1596,6 +1596,7 @@ class FocusManager with DiagnosticableTreeMixin, ChangeNotifier {
/// [FocusManager] notifies.
void
removeHighlightModeListener
(
ValueChanged
<
FocusHighlightMode
>
listener
)
=>
_listeners
.
remove
(
listener
);
@pragma
(
'vm:notify-debugger-on-exception'
)
void
_notifyHighlightModeListeners
()
{
if
(
_listeners
.
isEmpty
)
{
return
;
...
...
packages/flutter/lib/src/widgets/framework.dart
View file @
2a8dba4a
...
...
@@ -2505,6 +2505,7 @@ class BuildOwner {
/// [debugPrintBuildScope] to true. This is useful when debugging problems
/// involving widgets not getting marked dirty, or getting marked dirty too
/// often.
@pragma
(
'vm:notify-debugger-on-exception'
)
void
buildScope
(
Element
context
,
[
VoidCallback
?
callback
])
{
if
(
callback
==
null
&&
_dirtyElements
.
isEmpty
)
return
;
...
...
@@ -2833,6 +2834,10 @@ class BuildOwner {
///
/// After the current call stack unwinds, a microtask that notifies listeners
/// about changes to global keys will run.
// TODO(goderbauer): Add pragma (and enable test in
// break_on_framework_exceptions_test.dart) once debugger breaks on correct
// line, https://github.com/dart-lang/sdk/issues/45684
// @pragma('vm:notify-debugger-on-exception')
void
finalizeTree
()
{
Timeline
.
startSync
(
'Finalize tree'
,
arguments:
timelineArgumentsIndicatingLandmarkEvent
);
try
{
...
...
@@ -4579,6 +4584,7 @@ abstract class ComponentElement extends Element {
/// Called automatically during [mount] to generate the first build, and by
/// [rebuild] when the element needs updating.
@override
@pragma
(
'vm:notify-debugger-on-exception'
)
void
performRebuild
()
{
if
(!
kReleaseMode
&&
debugProfileBuildsEnabled
)
Timeline
.
startSync
(
'
${widget.runtimeType}
'
,
arguments:
timelineArgumentsIndicatingLandmarkEvent
);
...
...
packages/flutter/lib/src/widgets/layout_builder.dart
View file @
2a8dba4a
...
...
@@ -115,6 +115,10 @@ class _LayoutBuilderElement<ConstraintType extends Constraints> extends RenderOb
}
void
_layout
(
ConstraintType
constraints
)
{
// TODO(goderbauer): When https://github.com/dart-lang/sdk/issues/45710 is
// fixed: refactor the anonymous closure below into a named one, apply the
// @pragma('vm:notify-debugger-on-exception') to it and enable the
// corresponding test in break_on_framework_exceptions_test.dart.
owner
!.
buildScope
(
this
,
()
{
Widget
built
;
try
{
...
...
packages/flutter/lib/src/widgets/router.dart
View file @
2a8dba4a
...
...
@@ -760,6 +760,7 @@ class _CallbackHookProvider<T> {
/// Exceptions thrown by callbacks will be caught and reported using
/// [FlutterError.reportError].
@protected
@pragma
(
'vm:notify-debugger-on-exception'
)
T
invokeCallback
(
T
defaultValue
)
{
if
(
_callbacks
.
isEmpty
)
return
defaultValue
;
...
...
@@ -773,7 +774,7 @@ class _CallbackHookProvider<T> {
context:
ErrorDescription
(
'while invoking the callback for
$runtimeType
'
),
informationCollector:
()
sync
*
{
yield
DiagnosticsProperty
<
_CallbackHookProvider
<
T
>>(
'The
$runtimeType
that invoked the callback was
:
'
,
'The
$runtimeType
that invoked the callback was'
,
this
,
style:
DiagnosticsTreeStyle
.
errorProperty
,
);
...
...
packages/flutter/lib/src/widgets/sliver.dart
View file @
2a8dba4a
...
...
@@ -446,6 +446,7 @@ class SliverChildBuilderDelegate extends SliverChildDelegate {
}
@override
@pragma
(
'vm:notify-debugger-on-exception'
)
Widget
?
build
(
BuildContext
context
,
int
index
)
{
assert
(
builder
!=
null
);
if
(
index
<
0
||
(
childCount
!=
null
&&
index
>=
childCount
!))
...
...
packages/flutter_tools/test/integration.shard/break_on_framework_exceptions_test.dart
0 → 100644
View file @
2a8dba4a
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment