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代码:
- 创建标记接口:
public interface BadRequestExceptionMarker {}
- 让你的异常类实现该接口:
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 {}
- 在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
相关产品推荐
相关产品推荐

