You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用RxJS fromEvent连接命名SSE,如何捕获连接失败错误?

问题

我正在使用RxJS的fromEvent连接命名SSE事件,希望捕获连接丢失时的错误。以下是我的代码:

namedEvent() {
    try {
      const eventSource = new EventSource(
        'adress'
      );
      return fromEvent(eventSource, 'eventName').pipe(
        catchError((err) => {
          // handle the error
          console.log('Error:', err);
          return of(null);  // return an empty observable to prevent the stream from completing
        })
      );
    } catch (err) {
      // handle the error
      console.log('Error:', err);
      return of(null);  // return an empty observable to prevent the stream from completing
    }
  }

我在连接初始化时使用try/catch块捕获错误,在Observable中使用RxJS的catchError捕获流错误,但当前代码没有任何错误输出,浏览器仅抛出net::ERR_NAME_NOT_RESOLVED错误,网络标签页显示“failed to load response data”。请问该如何捕获这类错误?

解决方案

你当前写法捕获不到错误的核心原因:

  • try/catch只能捕获同步异常,而EventSource的连接错误是异步触发的,初始化阶段不会立即抛出异常;
  • fromEvent(eventSource, 'eventName')仅监听了自定义命名事件,没监听EventSource原生的error事件,且catchError只能捕获当前Observable流内的错误,SSE连接错误不会流入这个事件流。

下面提供两种可行的实现方式:

方式一:合并事件流与错误流统一处理

将命名事件流和错误流合并,用RxJS操作符统一捕获错误:

import { fromEvent, merge, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

namedEvent() {
  const eventSource = new EventSource('address');
  
  // 监听自定义命名事件
  const eventStream = fromEvent(eventSource, 'eventName');
  // 监听error事件,将错误转为Observable的错误通知
  const errorStream = fromEvent(eventSource, 'error').pipe(
    map(() => {
      throw new Error('SSE连接失败或已断开');
    })
  );
  
  // 合并两个流,统一处理错误
  return merge(eventStream, errorStream).pipe(
    catchError((err) => {
      console.log('Error:', err.message);
      // 关闭连接避免内存泄漏
      eventSource.close();
      return of(null);
    })
  );
}

方式二:直接绑定EventSource错误回调

不通过RxJS流处理,直接给EventSource绑定onerror回调:

import { fromEvent, of } from 'rxjs';
import { catchError } from 'rxjs/operators';

namedEvent() {
  const eventSource = new EventSource('address');
  
  // 单独处理SSE连接错误
  eventSource.onerror = (event) => {
    console.log('SSE连接错误:', event);
    eventSource.close();
    // 这里可添加重连、告警等逻辑
  };
  
  return fromEvent(eventSource, 'eventName').pipe(
    catchError((err) => {
      console.log('事件流内部错误:', err);
      eventSource.close();
      return of(null);
    })
  );
}

额外注意事项

  • 错误发生后务必调用eventSource.close()关闭连接,避免无效重连和内存泄漏;
  • 若需要自动重连,可在错误回调中延迟重新创建EventSource实例;
  • net::ERR_NAME_NOT_RESOLVED这类网络错误会触发EventSource的error事件,上述两种方式都能正常捕获。

内容的提问来源于stack exchange,提问作者Sator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:15:54