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

Reactor doOnError:如何在方法参数中包含多种异常类型

解决方案

在Reactive Spring Boot中,你可以通过以下几种方式合并处理多种异常,避免重复的doOnError代码块。另外需要注意:doOnError是副作用操作,仅用于执行日志、资源清理等逻辑,不会改变流的响应结果——你原来的写法里,doOnError创建ResponseEntity是无效的,异常依然会向上传播,导致Spring返回500错误。正确的做法是用onErrorResume捕获异常并返回指定响应。

方案1:直接用逻辑或判断异常类型

通过instanceof结合逻辑或,在onErrorResume的谓词中一次性判断所有目标异常:

@PostMapping("/my-api")
public Mono<ResponseEntity<String>> save(@RequestBody JsonNode rawDto) {
    return myValidator.validate(rawDto)
            .flatMap(myService::save)
            .map(ResponseEntity::ok) // 构建成功响应
            .onErrorResume(
                error -> error instanceof MyValidationException 
                        || error instanceof MyBusinessLogicException 
                        || error instanceof MyRemoteApiException 
                        || error instanceof MyDataConstraintException,
                error -> Mono.just(ResponseEntity.badRequest().build())
            );
}

方案2:自定义标记接口(推荐,扩展性更强)

定义一个空的标记接口,让所有需要返回BAD_REQUEST的异常实现该接口,后续新增异常只需实现接口即可,无需修改Controller代码:

  1. 创建标记接口:
public interface BadRequestExceptionMarker {}
  1. 让你的异常类实现该接口:
public class MyValidationException extends RuntimeException implements BadRequestExceptionMarker {}
public class MyBusinessLogicException extends RuntimeException implements BadRequestExceptionMarker {}
public class MyRemoteApiException extends RuntimeException implements BadRequestExceptionMarker {}
public class MyDataConstraintException extends RuntimeException implements BadRequestExceptionMarker {}
  1. 在Controller中使用:
@PostMapping("/my-api")
public Mono<ResponseEntity<String>> save(@RequestBody JsonNode rawDto) {
    return myValidator.validate(rawDto)
            .flatMap(myService::save)
            .map(ResponseEntity::ok)
            .onErrorResume(
                BadRequestExceptionMarker.class::isInstance,
                error -> Mono.just(ResponseEntity.badRequest().build())
            );
}

方案3:提取判断逻辑到工具方法

如果不想用标记接口,可以把异常判断逻辑提取到静态工具方法中,让代码更简洁:

// 工具类或当前Controller中的静态方法
private static boolean isBadRequestException(Throwable error) {
    return error instanceof MyValidationException
            || error instanceof MyBusinessLogicException
            || error instanceof MyRemoteApiException
            || error instanceof MyDataConstraintException;
}

// Controller方法中使用
@PostMapping("/my-api")
public Mono<ResponseEntity<String>> save(@RequestBody JsonNode rawDto) {
    return myValidator.validate(rawDto)
            .flatMap(myService::save)
            .map(ResponseEntity::ok)
            .onErrorResume(
                YourControllerClass::isBadRequestException,
                error -> Mono.just(ResponseEntity.badRequest().build())
            );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 21:32:20