【问题标题】:Why can't i catch this TimeoutException为什么我不能捕捉到这个 TimeoutException
【发布时间】:2021-08-08 17:17:54
【问题描述】:

我目前正在为要控制连接超时值的 Web 构建 Stomp WebSocket 连接。这是我的连接方法:

Future<WebSocketChannel> connect(StompConfig config) {
  final completer = Completer<HtmlWebSocketChannel>();
  final webSocket = WebSocket(config.url)..binaryType = BinaryType.list.value;
  var onOpenEvent = webSocket.onOpen.first;
  if (config.connectionTimeout.inMilliseconds > 0) {
    onOpenEvent = onOpenEvent.timeout(config.connectionTimeout);
  }
  onOpenEvent.then((value) {
    completer.complete(HtmlWebSocketChannel(webSocket));
  });
  webSocket.onError.first.then((err) {
    completer.completeError(WebSocketChannelException.from(err));
  });

  return completer.future;
}

我就是这样称呼它的:

try {
    _channel = await platform.connect(config);
} catch (err) {
   print('Caught error');
}

遗憾的是,我似乎无法捕捉到onOpenEvent.timeout(..) 抛出的TimeoutException。相反,它只是打印这个(看似未捕获的异常):

Error: TimeoutException after 0:00:05.000000: Future not completed
    at Object.createErrorWithStack (http://localhost:59275/dart_sdk.js:5044:12)
    at Object._rethrow (http://localhost:59275/dart_sdk.js:37476:16)
    at async._AsyncCallbackEntry.new.callback (http://localhost:59275/dart_sdk.js:37472:13)
    at Object._microtaskLoop (http://localhost:59275/dart_sdk.js:37332:13)
    at _startMicrotaskLoop (http://localhost:59275/dart_sdk.js:37338:13)
    at http://localhost:59275/dart_sdk.js:33109:9

我做错了什么?我之前的代码看起来像这样并且适用于TimeoutException,但遗憾的是不适用于 WebSocket 引发的任何其他异常:

Future<WebSocketChannel> connect(StompConfig config) async {
  final webSocket = WebSocket(config.url)..binaryType = BinaryType.list.value;
  var onOpenEvent = webSocket.onOpen.first;
  if (config.connectionTimeout.inMilliseconds > 0) {
    onOpenEvent = onOpenEvent.timeout(config.connectionTimeout);
  }
  await onOpenEvent;
  return HtmlWebSocketChannel(webSocket);
}

感谢您的任何建议!

【问题讨论】:

    标签: dart websocket dart-html


    【解决方案1】:

    可以捕捉到异常,只是你没有。 声明

      onOpenEvent.then((value) {
        completer.complete(HtmlWebSocketChannel(webSocket));
      });
    

    监听onOpenEvent 未来,并创建一个新的Future 作为结果。 当 onOpenEvent 以超时异常结束时,此 then 调用会收到错误,并且由于它不处理异常,因此它返回的未来也会以相同的异常完成。

    没有人接触过这个未来,因为上面的语句丢弃了它,因此这个未来的结果是一个未处理的错误

    您之前的代码有效的原因是await onOpenEvent(重新)抛出该错误并使其成为整个connect 调用的结果。

    新代码无法让该错误到达 connect 函数调用,onOpenEvent.then(...) 未来可能会在 connect 返回后完成。

    您可以尝试在then 调用中添加错误处理程序:

      onOpenEvent.then((value) {
        completer.complete(HtmlWebSocketChannel(webSocket));
      }, onError: (error, StackTrace stackTrace) {
        if (!completer.isCompleted) completer.completeError(error, stackTrace);
      });
      webSocket.onError.first.then((err) {
        if (!completer.isCompleted) {    
          completer.completeError(WebSocketChannelException.from(err));
        }
      });
    

    【讨论】:

    • 谢谢!这就说得通了。我改为在CompleterFuture 上设置一个超时并返回那个未来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 2021-07-25
    相关资源
    最近更新 更多