Commit 1393b4c6 authored by Ian Hickson's avatar Ian Hickson

Merge pull request #781 from Hixie/better-exceptions

Better exception handling for rendering library.
parents a4182561 d99641dd
...@@ -512,7 +512,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -512,7 +512,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
String toStringName() { String toStringName() {
String header = super.toStringName(); String header = super.toStringName();
if (_overflow > 0.0) if (_overflow is double && _overflow > 0.0)
header += ' OVERFLOWING'; header += ' OVERFLOWING';
return header; return header;
} }
......
...@@ -318,6 +318,24 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -318,6 +318,24 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
// Override in subclasses with children and call the visitor for each child. // Override in subclasses with children and call the visitor for each child.
void visitChildren(RenderObjectVisitor visitor) { } void visitChildren(RenderObjectVisitor visitor) { }
dynamic debugExceptionContext = '';
static dynamic _debugLastException;
bool _debugReportException(dynamic exception, String method) {
if (!inDebugBuild) {
print('Uncaught exception in ${method}():\n$exception');
return false;
}
if (!identical(exception, _debugLastException)) {
print('-- EXCEPTION --');
print('An exception was raised during ${method}().');
'The following RenderObject was being processed when the exception was fired:\n${this}'.split('\n').forEach(print);
if (debugExceptionContext != '')
'The RenderObject had the following exception context:\n${debugExceptionContext}'.split('\n').forEach(print);
_debugLastException = exception;
}
return true;
}
static bool _debugDoingLayout = false; static bool _debugDoingLayout = false;
static bool get debugDoingLayout => _debugDoingLayout; static bool get debugDoingLayout => _debugDoingLayout;
bool _debugDoingThisResize = false; bool _debugDoingThisResize = false;
...@@ -443,10 +461,8 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -443,10 +461,8 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
return true; return true;
}); });
} catch (e) { } catch (e) {
print('Exception raised during layout:\n${e}\nContext:\n${this}'); if (_debugReportException(e, 'layoutWithoutResize'))
if (inDebugBuild)
rethrow; rethrow;
return;
} }
_needsLayout = false; _needsLayout = false;
markNeedsPaint(); markNeedsPaint();
...@@ -482,14 +498,19 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -482,14 +498,19 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
_debugActiveLayout = this; _debugActiveLayout = this;
return true; return true;
}); });
performLayout(); try {
assert(() { performLayout();
_debugActiveLayout = debugPreviousActiveLayout; assert(() {
_debugDoingThisLayout = false; _debugActiveLayout = debugPreviousActiveLayout;
_debugMutationsLocked = false; _debugDoingThisLayout = false;
return true; _debugMutationsLocked = false;
}); return true;
assert(debugDoesMeetConstraints()); });
assert(debugDoesMeetConstraints());
} catch (e) {
if (_debugReportException(e, 'layout'))
rethrow;
}
_needsLayout = false; _needsLayout = false;
markNeedsPaint(); markNeedsPaint();
assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer is cleverer assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer is cleverer
...@@ -666,10 +687,8 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -666,10 +687,8 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
_paintWithContext(context, Offset.zero); _paintWithContext(context, Offset.zero);
context.endRecording(); context.endRecording();
} catch (e) { } catch (e) {
print('Exception raised during _paintLayer:\n${e}\nContext:\n${this}'); if (_debugReportException(e, '_repaint'))
if (inDebugBuild)
rethrow; rethrow;
return;
} }
} }
void _paintWithContext(PaintingContext context, Offset offset) { void _paintWithContext(PaintingContext context, Offset offset) {
......
...@@ -6,6 +6,7 @@ import 'dart:async'; ...@@ -6,6 +6,7 @@ import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'dart:sky' as sky; import 'dart:sky' as sky;
import 'package:sky/base/debug.dart';
import 'package:sky/base/hit_test.dart'; import 'package:sky/base/hit_test.dart';
import 'package:sky/base/scheduler.dart' as scheduler; import 'package:sky/base/scheduler.dart' as scheduler;
import 'package:sky/mojo/activity.dart'; import 'package:sky/mojo/activity.dart';
...@@ -955,6 +956,13 @@ abstract class RenderObjectWrapper extends Widget { ...@@ -955,6 +956,13 @@ abstract class RenderObjectWrapper extends Widget {
_ancestor = old._ancestor; _ancestor = old._ancestor;
assert(_renderObject != null); assert(_renderObject != null);
} }
if (inDebugBuild) {
try {
throw null;
} catch (_, stack) {
_renderObject.debugExceptionContext = stack;
}
}
assert(_renderObject == renderObject); // in case a subclass reintroduces it assert(_renderObject == renderObject); // in case a subclass reintroduces it
assert(renderObject != null); assert(renderObject != null);
assert(mounted); assert(mounted);
......
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