捕获R2dbcRepository异常并抛出自定义业务异常的正确方法
正确实现方案
针对你的需求,结合Reactor响应式编程的特性,正确的代码需要同时处理无记录返回(Empty Mono)和捕获IllegalStateException两种场景,写法如下:
officeRepository.findById(officeId) // 当findById返回空Mono(无匹配记录)时,抛出自定义异常 .switchIfEmpty(Mono.error(new RequestedNotFoundException("Office not found"))) // 捕获findById抛出的IllegalStateException,转为自定义业务异常 .onErrorResume(IllegalStateException.class, e -> Mono.error(new RequestedNotFoundException("Office not found", e)));
你之前写法的问题分析
第一种handle写法:
handle仅在Mono发出元素或错误时执行,而findById无匹配记录时返回的是Empty Mono,不会触发handle的回调;另外即使有元素返回,你的代码也没有调用synchronousSink.next(officeEntity)传递数据,会导致正常结果丢失。第二种onErrorResume写法:
仅处理异常场景,但无匹配记录是Empty Mono而非异常,因此不会触发;同时代码存在语法错误(末尾缺少闭合括号)。第三种嵌套Mono写法:
使用map调用findById会导致返回Mono<Mono<OfficeEntity>>的嵌套结构,应该用flatMap来扁平化处理;同样只处理了异常,没有覆盖无记录的场景。
补充说明
R2dbcRepository的findById方法默认行为是:找到记录返回包含实体的Mono,无匹配记录返回Empty Mono,不会主动抛出IllegalStateException。如果你的场景中确实会抛出该异常,大概率是后续同步操作(比如调用block())导致的,此时上述代码依然能覆盖异常捕获的需求。
内容的提问来源于stack exchange,提问作者hamed
相关产品推荐
相关产品推荐

