如何在Dart(Flutter)的回调函数中捕获异常?

时间:2019-06-28 13:31:28

标签: flutter dart

我在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:[错误:flutter / lib / ui / ui_dart_state.cc(148)]未处理的异常:异常:有我的异常

E / flutter:#0 MyChat.processMsg

2 个答案:

答案 0 :(得分: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");
  }
}

答案 1 :(得分:0)

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

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('');

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

我希望这样做