IOException我在局部已经捕获到了,但是全局中还是会依旧抛出

Blade 已结 2 128
zzzcf
zzzcf 剑宗 2025-05-13 13:19

一、该问题的重现步骤是什么?

1. 我在处理sse心跳感应时,每10s发送一次来确保连接存活,在这期间对于前端流关闭时,我通过catch IOException 来捕获该异常,局部是能够捕获到,捕获到之后还是会进入到全局异常中

2. 

3.


二、你期待的结果是什么?实际看到的又是什么?

我希望局部捕获之后,全局不再抛出

三、你正在使用的是什么产品,什么版本?在什么操作系统上?


四、请提供详细的错误堆栈信息,这很重要。


五、若有更多详细信息,请在下面提供。

image.png

image.png

image.png

2条回答
  •  admin
    admin (最佳回答者)
    2025-05-13 13:22

    SseEmitter.send() 抛出的异常不是立即终止,而是异步触发回调,SseEmitter 背后是基于 Servlet 异步响应实现的。


    如果连接关闭或网络中断,send() 内部会触发 IOException,但这异常通常被封装并延迟抛出(在另一个线程中)。


    可以在OnErr的时候处理下,你按照下面的方式看看

    @GetMapping("/sse")
    public SseEmitter stream() {
        SseEmitter emitter = new SseEmitter(0L);
        emitter.onCompletion(() -> log.info("SSE 连接已完成"));
        emitter.onTimeout(() -> {
            log.warn("SSE 超时");
            emitter.complete();
        });
        emitter.onError((Throwable t) -> {
            log.error("SSE 出错", t);
            // 可选:emitter.completeWithError(t); 或 emitter.complete();
        });
        try {
            emitter.send(SseEmitter.event().data("hello"));
        } catch (IOException e) {
            log.error("发送 SSE 数据失败", e);
            // 这里你可以调用 completeWithError,触发 onError 回调
            emitter.completeWithError(e);
        }
        return emitter;
    }



    另外请给我们邮箱:bladejava@qq.com 发一个邮件提供授权公司名,登记为商业账号后方可进行商业版问题答疑。

    作者追问:2025-05-13 13:22

    加上上述代码之后,依旧会出现这样的情况,无法将异常给屏蔽

    image.png

    image.png

    0 讨论(1)
  • 2025-05-13 14:30

    最后加上了局部异常处理器来覆盖全局处理器暂时解决

    0 讨论(0)
代码语言
提交回复