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 ...@@ -287,9 +287,18 @@ mixin GestureBinding on BindingBase implements HitTestable, HitTestDispatcher, H
void _handlePointerDataPacket(ui.PointerDataPacket packet) { void _handlePointerDataPacket(ui.PointerDataPacket packet) {
// We convert pointer data to logical pixels so that e.g. the touch slop can be // We convert pointer data to logical pixels so that e.g. the touch slop can be
// defined in a device-independent manner. // defined in a device-independent manner.
_pendingPointerEvents.addAll(PointerEventConverter.expand(packet.data, window.devicePixelRatio)); try {
if (!locked) { _pendingPointerEvents.addAll(PointerEventConverter.expand(packet.data, window.devicePixelRatio));
_flushPointerEventQueue(); 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 ...@@ -35,14 +35,20 @@ class TestGestureFlutterBinding extends BindingBase with GestureBinding, Schedul
return _instance!; return _instance!;
} }
HandleEventCallback? callback; HandleEventCallback? onHandlePointerEvent;
@override
void handlePointerEvent(PointerEvent event) {
onHandlePointerEvent?.call(event);
super.handlePointerEvent(event);
}
HandleEventCallback? onHandleEvent;
@override @override
void handleEvent(PointerEvent event, HitTestEntry entry) { void handleEvent(PointerEvent event, HitTestEntry entry) {
super.handleEvent(event, entry); super.handleEvent(event, entry);
if (callback != null) { onHandleEvent?.call(event);
callback?.call(event);
}
} }
} }
...@@ -58,7 +64,7 @@ void main() { ...@@ -58,7 +64,7 @@ void main() {
); );
final List<PointerEvent> events = <PointerEvent>[]; final List<PointerEvent> events = <PointerEvent>[];
binding.callback = events.add; binding.onHandleEvent = events.add;
GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet); GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 2); expect(events.length, 2);
...@@ -76,7 +82,7 @@ void main() { ...@@ -76,7 +82,7 @@ void main() {
); );
final List<PointerEvent> events = <PointerEvent>[]; final List<PointerEvent> events = <PointerEvent>[];
binding.callback = events.add; binding.onHandleEvent = events.add;
GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet); GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 3); expect(events.length, 3);
...@@ -101,7 +107,7 @@ void main() { ...@@ -101,7 +107,7 @@ void main() {
GestureBinding.instance.pointerRouter.addGlobalRoute(pointerRouterEvents.add); GestureBinding.instance.pointerRouter.addGlobalRoute(pointerRouterEvents.add);
final List<PointerEvent> events = <PointerEvent>[]; final List<PointerEvent> events = <PointerEvent>[];
binding.callback = events.add; binding.onHandleEvent = events.add;
GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet); GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 3); expect(events.length, 3);
...@@ -126,7 +132,7 @@ void main() { ...@@ -126,7 +132,7 @@ void main() {
); );
final List<PointerEvent> events = <PointerEvent>[]; final List<PointerEvent> events = <PointerEvent>[];
binding.callback = events.add; binding.onHandleEvent = events.add;
GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet); GestureBinding.instance.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 2); expect(events.length, 2);
...@@ -143,7 +149,7 @@ void main() { ...@@ -143,7 +149,7 @@ void main() {
); );
final List<PointerEvent> events = <PointerEvent>[]; final List<PointerEvent> events = <PointerEvent>[];
binding.callback = (PointerEvent event) { binding.onHandleEvent = (PointerEvent event) {
events.add(event); events.add(event);
if (event is PointerDownEvent) { if (event is PointerDownEvent) {
binding.cancelPointer(event.pointer); binding.cancelPointer(event.pointer);
...@@ -389,7 +395,7 @@ void main() { ...@@ -389,7 +395,7 @@ void main() {
); );
final List<PointerEvent> events = <PointerEvent>[]; final List<PointerEvent> events = <PointerEvent>[];
binding.callback = events.add; binding.onHandleEvent = events.add;
binding.platformDispatcher.onPointerDataPacket?.call(packet); binding.platformDispatcher.onPointerDataPacket?.call(packet);
expect(events.length, 3); expect(events.length, 3);
...@@ -397,4 +403,28 @@ void main() { ...@@ -397,4 +403,28 @@ void main() {
expect(events[1], isA<PointerPanZoomUpdateEvent>()); expect(events[1], isA<PointerPanZoomUpdateEvent>());
expect(events[2], isA<PointerPanZoomEndEvent>()); 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