[英]How to catch exception in a callback function in Dart (Flutter)?
I'm using WebSocket variable in my MyWebSocket
class. 我在
MyWebSocket
类中使用WebSocket变量。 For listen i give a callback function as parameter. 对于侦听,我提供一个回调函数作为参数。 If this callback function throws an exception in calling class
MyChat
, then i can not catch that exception anywhere. 如果此回调函数在调用类
MyChat
引发异常,则我无法在任何地方捕获该异常。
My simplified code is: 我的简化代码是:
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");
}
}
I have built try-catch
in every possible place to catch exceptions - no success, i got only unhandled exception: 我在每个可能的地方都建立了
try-catch
来捕获异常-没有成功,我只有未处理的异常:
E/flutter: [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: Exception: There is my Exception E / flutter:[错误:flutter / lib / ui / ui_dart_state.cc(148)]未处理的异常:异常:有我的异常
E/flutter: #0 MyChat.processMsg E / Flutter:#0 MyChat.processMsg
Beware that you cannot use the passed listener as a key for later removal. 请注意,您不能将传递的侦听器用作以后删除的键。 For that you can pass the new listener created in MyWebSocket class when listen() is called, then use this key to remove the listener.
为此,可以在调用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");
}
}
You need to handle it inside your processMsg 您需要在您的过程中处理它
If you analyze carefully the execution of your code the _ws.listent
register a listener for when you receive a message and that will happen in the FUTURE, but you don't get an error WHILE you are REGISTERING your listener that's why that doesn't work the way you expect. 如果您仔细分析代码的执行情况,
_ws.listent
将在您收到消息时注册一个侦听器,这将在将来发生,但不会出现错误,而您正在注册侦听器,这就是为什么不这样做以您期望的方式工作。
processMsg
will do something in the future, it will throw an error and it's at the end of the pipeline. processMsg
将来会做一些事情,会引发错误,并且会在管道的尽头。
You are simulating an exception and nothing is handling it, it happens in a different stack frame, in the future. 您正在模拟一个异常,但是什么也没有处理,将来它会在不同的堆栈帧中发生。
The void listen({void Function(dynamic) myOnListen})
function execution is long gone when you receive and you precessMsg
. 当您收到并
precessMsg
时, void listen({void Function(dynamic) myOnListen})
函数执行已久。
Alternatively you could do: 或者,您可以执行以下操作:
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('');
and then pass processMsgWithTryCatch
down to your listener if you don't want to handle inside processMsg
如果不想在
processMsg
内部处理,则将processMsgWithTryCatch
传递给您的侦听器
I hope that make sense 我希望这有道理
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.