Unverified Commit 578edfc8 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Catch errors thrown while handling pointer events (#119577)

parent bc8927c7
......@@ -287,9 +287,18 @@ mixin GestureBinding on BindingBase implements HitTestable, HitTestDispatcher, H
void _handlePointerDataPacket(ui.PointerDataPacket packet) {
// We convert pointer data to logical pixels so that e.g. the touch slop can be
// defined in a device-independent manner.
_pendingPointerEvents.addAll(PointerEventConverter.expand(packet.data, window.devicePixelRatio));
if (!locked) {
_flushPointerEventQueue();
try {
_pendingPointerEvents.addAll(PointerEventConverter.expand(packet.data, window.devicePixelRatio));
if (!locked) {
_flushPointerEventQueue();
}
} catch (error, stack) {
FlutterError.reportError(FlutterErrorDetails(
exception: error,
stack: stack,
library: 'gestures library',
context: ErrorDescription('while handling a pointer data packet'),
));
}
}
......
......@@ -35,14 +35,20 @@ class TestGestureFlutterBinding extends BindingBase with GestureBinding, Schedul
return _instance!;
}
HandleEventCallback? callback;
HandleEventCallback? onHandlePointerEvent;
@override
void handlePointerEvent(PointerEvent event) {
onHandlePointerEvent?.call(event);
super.handlePointerEvent(event);
}
HandleEventCallback? onHandleEvent;
@override
void handleEvent(PointerEvent event, HitTestEntry entry) {
super.handleEvent(event, entry);
if (callback != null) {
callback?.call(event);
}
onHandleEvent?.call(event);
}
}
......@@ -58,7 +64,7 @@ void main() {
);
final List<PointerEvent> events = <PointerEvent>[];
binding.callback = events.add;
binding.onHandleEvent = events.add;
GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 2);
......@@ -76,7 +82,7 @@ void main() {
);
final List<PointerEvent> events = <PointerEvent>[];
binding.callback = events.add;
binding.onHandleEvent = events.add;
GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 3);
......@@ -101,7 +107,7 @@ void main() {
GestureBinding.instance.pointerRouter.addGlobalRoute(pointerRouterEvents.add);
final List<PointerEvent> events = <PointerEvent>[];
binding.callback = events.add;
binding.onHandleEvent = events.add;
GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 3);
......@@ -126,7 +132,7 @@ void main() {
);
final List<PointerEvent> events = <PointerEvent>[];
binding.callback = events.add;
binding.onHandleEvent = events.add;
GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 2);
......@@ -143,7 +149,7 @@ void main() {
);
final List<PointerEvent> events = <PointerEvent>[];
binding.callback = (PointerEvent event) {
binding.onHandleEvent = (PointerEvent event) {
events.add(event);
if (event is PointerDownEvent) {
binding.cancelPointer(event.pointer);
......@@ -389,7 +395,7 @@ void main() {
);
final List<PointerEvent> events = <PointerEvent>[];
binding.callback = events.add;
binding.onHandleEvent = events.add;
binding.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 3);
......@@ -397,4 +403,28 @@ void main() {
expect(events[1], isA<PointerPanZoomUpdateEvent>());
expect(events[2], isA<PointerPanZoomEndEvent>());
});
test('Error handling', () {
const ui.PointerDataPacket packet = ui.PointerDataPacket(
data: <ui.PointerData>[
ui.PointerData(change: ui.PointerChange.down),
ui.PointerData(change: ui.PointerChange.up),
],
);
final List<String> events = <String>[];
binding.onHandlePointerEvent = (PointerEvent event) { throw Exception('zipzapzooey $event'); };
FlutterError.onError = (FlutterErrorDetails details) { events.add(details.toString()); };
try {
GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 1);
expect(events[0], contains('while handling a pointer data\npacket')); // The default stringifying behavior uses 65 character wrapWidth.
expect(events[0], contains('zipzapzooey'));
expect(events[0], contains('PointerDownEvent'));
expect(events[0], isNot(contains('PointerUpEvent'))); // Failure happens on the first message, remaining messages aren't processed.
} finally {
binding.onHandlePointerEvent = null;
FlutterError.onError = FlutterError.presentError;
}
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment