onerror是SSE连接生命周期事件处理器,用于响应网络/协议层问题,不捕获JS异常;需结合readyState判断状态、手动实现可控重连,并在onmessage等回调中单独try/catch处理业务错误。

在 JavaScript 的 SSE(Server-Sent Events)客户端中,onerror 不是“异常”,而是一个事件处理器,用于响应连接失败、重连中断或服务器关闭流等网络/协议层面的问题。它不会捕获 throw 或运行时错误,也不能用 try/catch 拦截。正确做法是合理设置 onerror 回调,并配合状态管理与重连逻辑。
onerror 触发的典型场景
EventSource.onerror 会在以下情况被调用(注意:不带具体错误对象,仅触发):
- 初始连接失败(如 404、500、网络不通)
- 连接建立后意外断开(如服务器重启、超时、Nginx 关闭空闲连接)
- 接收到格式非法的事件流(如非 UTF-8、缺少冒号但又非注释行)
- 浏览器主动终止连接(如页面隐藏、内存回收)
基础 onerror 处理 + 状态判断
仅靠 event.target.readyState 可区分当前状态,避免误判:
const es = new EventSource('/api/events');
<p>es.onopen = () => console.log('✅ 连接已打开');
es.onmessage = e => console.log('? 收到消息:', e.data);</p><p>es.onerror = function(e) {
const { readyState } = this;
if (readyState === EventSource.CONNECTING) {
console.warn('⚠️ 正在尝试重连中(可能刚启动或断开)');
} else if (readyState === EventSource.CLOSED) {
console.error('❌ 连接已被显式关闭(调用了 close())');
} else {
console.error('? 连接异常中断,准备重试...');
// 此处可触发重连或上报
}
};
手动实现可控重连(推荐)
浏览器默认有指数退避重连,但不可控。建议禁用并自行管理:
立即学习“Java免费学习笔记(深入)”;
let es = null;
let retryCount = 0;
const MAX_RETRY = 5;
const BASE_DELAY = 1000;
<p>function connect() {
es?.close(); // 清理旧实例
es = new EventSource('/api/events', { withCredentials: true });</p><p>es.onopen = () => {
console.log('✅ SSE 已连接');
retryCount = 0; // 重置计数
};</p><p>es.onerror = (e) => {
console.warn(<code>SSE 错误(readyState=${es.readyState})</code>);</p><pre class="brush:php;toolbar:false;">if (es.readyState === EventSource.CONNECTING && retryCount < MAX_RETRY) {
retryCount++;
setTimeout(connect, Math.min(BASE_DELAY * retryCount, 30_000));
} else {
console.error('? 达到最大重试次数,停止自动重连');
// 可触发 UI 提示、上报监控、降级方案等
}};
es.addEventListener('custom-event', (e) => { console.log('? 自定义事件:', e.data); }); }
connect();
补充:捕获 JS 层面的解析/业务异常
onmessage 或自定义事件回调里的 JS 错误,需单独 try/catch:
es.onmessage = (e) => {
try {
const data = JSON.parse(e.data); // 可能抛 SyntaxError
process(data);
} catch (err) {
console.error('? 消息解析或处理失败:', err);
// 上报错误、跳过该条、触发告警等
}
};
不复杂但容易忽略:onerror 是连接生命周期钩子,不是异常处理器;真正要健壮,得结合 readyState 判断、手动重连、以及业务层独立错误捕获。


















