Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 控制台中未显示颤振异常_Flutter_Dart_Exception_Textfield - Fatal编程技术网

Flutter 控制台中未显示颤振异常

Flutter 控制台中未显示颤振异常,flutter,dart,exception,textfield,Flutter,Dart,Exception,Textfield,我正在调试一个颤振应用程序。我注意到,在某些情况下,异常会被抛出,但不会显示在控制台中。所以我花了一段时间才知道有例外。这是浪费了很多时间 下面是一个小代码片段来说明这个问题。使用RaisedButton显示异常,但不使用TextField。我必须添加一个try/catch来打印异常,否则它是不可见的 问题不是错误本身,问题是错误没有显示出来。请告诉我如何显示所有异常 void main() => runApp(Test()); class Test extends StatelessW

我正在调试一个颤振应用程序。我注意到,在某些情况下,异常会被抛出,但不会显示在控制台中。所以我花了一段时间才知道有例外。这是浪费了很多时间

下面是一个小代码片段来说明这个问题。使用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()),
        ),
      ),
    );
  }
}
如果你想的话,你可以去“颤振回购”

下面是关于它如何工作的基本解释

如果查看源代码,
RaisedButton.onPressed
被委托给
InkWell.onTap
,然后转到
InkResponse.onTap
,然后在以下内容的最后一行调用它:

void\u handleTap(构建上下文){
_currentSplash?.confirm();
_currentSplash=null;
updateHighlight(_HighlightType.pressed,值:false);
如果(widget.onTap!=null){
if(widget.enableffeedback)
反馈。forTap(上下文);
onTap();
}
}
这由
手势识别器
包装在
invokeCallback
中,执行
try catch
并将错误转换为
错误
,您可以在控制台上看到格式良好的错误

T invokeCallback(字符串名称,识别器回调,{String debugReport()}){
断言(回调!=null);
T结果;
试一试{
断言(){
if(DebugPrintRecognitizerCallBackstrace){
最终字符串report=debugReport!=null?debugReport():null;
//下一行中的19是所使用前缀的宽度
//_在arena.dart中调试LogDiagnostic。
最终字符串前缀=debugPrintGestureArenaDiagnostics?''*19+'❙ ' : '';
debugPrint(“$prefix$this calling$name callback.${report?.isNotEmpty==true?”$report:“}”);
}
返回true;
}());
结果=回调();
}捕获(异常、堆栈){
信息采集器;
断言(){
收集器=()同步*{
产生StringProperty('Handler',名称);
产生DiagnosticsProperty(“识别器”,此,样式:DiagnosticsTreeStyle.errorProperty);
};
返回true;
}());
FlatterError.reportError(FlatterErrorDetails(
例外:例外,,
堆栈:堆栈,
图书馆:"手势",,
上下文:ErrorDescription('处理手势时'),
信息收集器:收集器
));
}
返回结果;
}
另一方面,
TextField.onSubmitted
被传递给一个
EditableText.onSubmitted
,并在以下内容的最后一行调用它:

void\u结束编辑(bool应该取消焦点){
//现在用户已完成编辑,请执行任何必要的操作。
if(widget.onEditingComplete!=null){
widget.onEditingComplete();
}否则{
//如果开发人员未提供
//onEditingComplete回调:完成编辑并移除焦点。
widget.controller.clearComposing();
如果(应该取消焦点)
widget.focusNode.unfocus();
}
//使用用户提交的内容调用可选回调。
if(widget.onSubmitted!=null)
widget.onSubmitted(_value.text);
}
这由MethodChannel包装:

Future\u handleAsMethodCall(ByteData消息,Future处理程序(MethodCall调用))异步{
最终方法调用=codec.decodeMethodCall(消息);
试一试{
返回codec.encodeSuccessDevelope(等待处理程序(调用));
}平台上异常捕获(e){
返回codec.encodeErrorEnvelope(
代码:e.code,
信息:e.message,
细节:即细节,
);
}关于丢失插件异常{
返回null;
}捕获(e){
返回codec.encodeErrorEnvelope(代码:“error”,消息:e.toString(),详细信息:null);
}
}
最后一个
catch(e)
被激活,然后您就看不到错误了


我怀疑如果您编译应用程序以发布,您会看到它,因为Dart VM在异步代码的调试模式下传递异常方面存在问题(我在这里过于简化了)。

这最终是一个有趣的发现

TextField
onSubmitted
方法(以及
TextFormField
onfielsubmitted
方法)是从
EditableText
基类的
performation
方法调用的,该基类最终作为平台频道消息的结果调用(特别是说“我现在编辑完这个文本字段了”的消息)。在
MethodChannel
类中,负责将事件传递给小部件的方法是:

Future\u handleAsMethodCall(ByteData消息,Future处理程序(MethodCall调用))异步{
最终方法调用=codec.decodeMethodCall(消息);
试一试{
返回codec.encodeSuccessDevelope(等待处理程序(调用));
}平台上异常捕获(e){
返回codec.encodeErrorEnvelope(
代码:e.code,
信息:e.message,
细节:即细节,
);
}关于丢失插件异常{
返回null;
}捕获(e){
返回codec.encodeErrorEnvelope(代码:“error”,消息:e.toString(),详细信息:null);
}
}
如您所见,方法调用被包装在一个try/catch中,它吸收错误并将其作为错误响应返回给平台,而不是让错误自然冒泡。其结果是错误消息由内部
BinaryMessenger
处理,而不是由Dart本身处理。从那里它结束在该方法中,这是一种固有的方法,也是一个研究的死胡同(除非您了解颤振的平台规范)