如何解决控制台中未显示Flutter异常
我正在尝试调试Flutter应用。我注意到在某些情况下会引发异常,但不会在控制台中显示。所以花了我一段时间才知道有一个例外。这浪费了很多时间。
这是一个小代码段,以显示该问题。使用RaisedButton会显示异常,但不会显示TextField
。我被迫添加try / catch来打印异常,否则它是不可见的。
问题不在于错误本身,问题在于未显示错误。请告诉我如何显示所有异常。
void main() => runApp(Test());
class Test extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
// EXCEPTION CAUGHT:
// child: RaisedButton(child: Text('Test'),onPressed: () => throw Exception()),// EXCEPTION NOT CAUGHT:
child: TextField(onSubmitted: (value) => throw Exception()),),);
}
}
解决方法
这最终是一次有趣的狩猎。
{{1}的onSubmitted
方法(以及TextField
的{{1}}方法)是从{{ 1}}基类,它最终被称为平台通道消息(特别是显示“我现在已经编辑完此文本字段”的消息)的结果。在onFieldSubmitted
类中,负责将事件传递给小部件的方法是_handleAsMethodCall
方法:
TextFormField
如您所见,方法调用被包装在try / catch中,该try / catch吸收错误并将错误作为错误响应返回到平台,而不是让错误自然冒泡。这样的结果是错误消息是由内部performAction
处理的,而不是由Dart本身处理的。从那里开始,它以Window._respondToPlatformMessage
方法结束,该方法是一种本机绑定方法,并且是调查性的死胡同(除非您了解Flutter特定于平台的本机实现)。
我不确定这是预期的行为还是错误,但是无论哪种情况,结果似乎都是平台/方法通道系统吸收了错误。我正在Flutter GitHub页面上为此设计一个问题,并将在发布问题时使用链接更新此答案。
编辑:问题页面为here。
,如果需要,可以在Flutter仓库中file this as an issue。
这是其工作原理的基本说明。
如果您查看源代码,则将@Test
public void myTest() {
webClient.get()
.uri("uri_path")
.header("Content-Type","application/json")
.accept("application/json")
.exchange()
.expectedStatus.is2xxxSuccessful();
}
委派给RaisedButton.onPressed
,然后将其转到InkWell.onTap
,然后在最后一行调用它:
InkResponse.onTap
这由 void _handleTap(BuildContext context) {
_currentSplash?.confirm();
_currentSplash = null;
updateHighlight(_HighlightType.pressed,value: false);
if (widget.onTap != null) {
if (widget.enableFeedback)
Feedback.forTap(context);
widget.onTap();
}
}
包裹在GestureRecognizer
中,该invokeCallback
执行try-catch
并将错误转换为FlutterError
,您在控制台上看到的格式很好。 >
T invokeCallback<T>(String name,RecognizerCallback<T> callback,{ String debugReport() }) {
assert(callback != null);
T result;
try {
assert(() {
if (debugPrintRecognizerCallbacksTrace) {
final String report = debugReport != null ? debugReport() : null;
// The 19 in the line below is the width of the prefix used by
// _debugLogDiagnostic in arena.dart.
final String prefix = debugPrintGestureArenaDiagnostics ? ' ' * 19 + '❙ ' : '';
debugPrint('$prefix$this calling $name callback.${ report?.isNotEmpty == true ? " $report" : "" }');
}
return true;
}());
result = callback();
} catch (exception,stack) {
InformationCollector collector;
assert(() {
collector = () sync* {
yield StringProperty('Handler',name);
yield DiagnosticsProperty<GestureRecognizer>('Recognizer',this,style: DiagnosticsTreeStyle.errorProperty);
};
return true;
}());
FlutterError.reportError(FlutterErrorDetails(
exception: exception,stack: stack,library: 'gesture',context: ErrorDescription('while handling a gesture'),informationCollector: collector
));
}
return result;
}
另一方面,TextField.onSubmitted
被传递到EditableText.onSubmitted
,并在以下一行的最后一行被调用:
void _finalizeEditing(bool shouldUnfocus) {
// Take any actions necessary now that the user has completed editing.
if (widget.onEditingComplete != null) {
widget.onEditingComplete();
} else {
// Default behavior if the developer did not provide an
// onEditingComplete callback: Finalize editing and remove focus.
widget.controller.clearComposing();
if (shouldUnfocus)
widget.focusNode.unfocus();
}
// Invoke optional callback with the user's submitted content.
if (widget.onSubmitted != null)
widget.onSubmitted(_value.text);
}
这由MethodChannel包装:
Future<ByteData> _handleAsMethodCall(ByteData message,Future<dynamic> handler(MethodCall call)) async {
final MethodCall call = codec.decodeMethodCall(message);
try {
return codec.encodeSuccessEnvelope(await handler(call));
} on PlatformException catch (e) {
return codec.encodeErrorEnvelope(
code: e.code,message: e.message,details: e.details,);
} on MissingPluginException {
return null;
} catch (e) {
return codec.encodeErrorEnvelope(code: 'error',message: e.toString(),details: null);
}
}
最后一个catch (e)
被激活,然后您看不到错误。
我怀疑是否将您的App编译为Release版本,您会看到它,因为Dart VM在调试模式下为异步代码交付异常时遇到了问题(我在这里简化了事情)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。