【问题标题】:How to catch exception in a callback function in Dart (Flutter)?如何在 Dart(Flutter)的回调函数中捕获异常?
【发布时间】:2019-06-28 13:31:28
【问题描述】:

我在 MyWebSocket 类中使用 WebSocket 变量。对于 listen,我给出一个回调函数作为参数。 如果此回调函数在调用类MyChat 时抛出异常,那么我无法在任何地方捕获该异常。

我的简化代码是:

class MyWebSocket {
  WebSocket _ws;
  ...
  // initialized in controller: _ws = WebSocket.connect(_some_url_);
  // everything works (connect, listen)
  ...
  void listen({void Function(dynamic) myOnListen}) {
    try {
      _ws.listen(myOnListen)
        .onError((e) => print("MyWebSocket in MyChat.onError: $e"));
    } catch (e) {
      print("Catched in MyWebSocket: $e");
    }
  }
}


class MyChat {
  MyWebSocket _chatWs = MyWebSocket();
  ...
  void initWS() {
    try {
      _chatWs.listen(myOnListen: processMsg);
    } catch (e) {
      print("Catched in MyChat: $e");
    }
  }

  void processMsg(dynamic msg) {
    if(_some_stuff_like_invalid_msg_or_not_logged_in_...)
      throw Exception("There is my Exception");
  }
}

我在每个可能的地方都建立了try-catch 来捕获异常——没有成功,我只有未处理的异常:

E/flutter: [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] 未处理异常:异常:有我的异常

E/flutter:#0 MyChat.processMsg

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    请注意,您不能将传递的侦听器用作以后删除的键。为此,您可以在调用 listen() 时传递在 MyWebSocket 类中创建的新侦听器,然后使用此键删除侦听器。

    class MyWebSocket {
      WebSocket _ws;
      void listen({void Function(dynamic) myOnListen, void Function(Error) onError}) {
        try {
          _ws.listen((){
            try {
              myOnListen({"label": "DATA"});
            } catch (e) {
              if(onError is Function)
              onError(e)
            }
          })
            .onError(onError);
        } catch (e) {
          print("Catched in MyWebSocket: $e");
        }
      }
    }
    
    
    class MyChat {
      MyWebSocket _chatWs = MyWebSocket();
      void initWS() {
        try {
          _chatWs.listen(myOnListen: processMsg, onError: (Error error){
            print("ERROR: "+error.toString());
          });
        } catch (e) {
          print("Catched in MyChat: $e");
        }
      }
    
      void processMsg(dynamic msg) {
        if(_some_stuff_like_invalid_msg_or_not_logged_in_...)
          throw Exception("There is my Exception");
      }
    }
    

    【讨论】:

      【解决方案2】:

      您需要在 processMsg
      中处理它 如果您仔细分析代码的执行,_ws.listent 会在您收到消息时注册一个侦听器,这将在未来发生,但是您在注册侦听器时不会收到错误,这就是为什么没有以您期望的方式工作。
      processMsg 将来会做一些事情,它会抛出一个错误并且它在管道的末端。
      您正在模拟一个异常并且没有任何处理它,它会在将来发生在不同的堆栈帧中。
      当您收到precessMsg 时,void listen({void Function(dynamic) myOnListen}) 函数的执行早已不复存在。
      或者你可以这样做:

      Function tryCatchHOF(Function cb) {
        decorated(dynamic param) {
          try {
            cb(param);
          } catch (e) {
            print("$e");
          }
        }
      
        ;
        return decorated;
      }
      
      void processMsg(dynamic msg) {
        if (true) throw Exception("There is my Exception");
      }
      
      var processMsgWithTryCatch = tryCatchHOF(processMsg);
        processMsgWithTryCatch('');
      

      如果您不想在processMsg 内部处理,则将processMsgWithTryCatch 传递给您的听众

      我希望这是有道理的

      【讨论】:

        猜你喜欢
        • 2011-03-25
        • 2019-11-10
        • 2019-12-31
        • 2023-01-20
        • 2018-01-27
        • 2015-06-25
        • 2019-09-20
        • 2014-06-30
        • 1970-01-01
        相关资源
        最近更新 更多