onerrormap 是 reactor 中将上游 onerror 信号的 throwable 映射为新 throwable 的操作符,仅在错误发生时触发,用于将技术异常转译为语义清晰的业务异常,不捕获异常也不改变流终止行为。

onErrorMap 是 Reactor 中用于将上游错误信号(Throwable)映射为另一个 Throwable 的操作符,常用于把底层技术异常(如 IOException、SQLException)转译为更语义清晰、可被业务层识别和处理的自定义业务异常(如 UserNotFoundException、InsufficientBalanceException)。
明确 onErrorMap 的作用时机与行为
它只在上游 Publisher 发出 onError 信号时触发,不会影响正常数据流;返回的新异常会作为新的 onError 信号向下传递。注意:它不“捕获”异常,也不改变流的终止行为,只是替换异常实例。
- 若 lambda 返回 null,Reactor 会抛出 NullPointerException 并作为新错误传播
- 若 lambda 抛出异常,该异常会替代原异常向下传递
- 它不改变错误是否终止流——Reactor 流遇到 onError 必然终止
基础用法:用 Function 映射异常类型
最常见场景是根据异常类型做分类转换。例如将数据库异常统一转为业务异常:
repository.findById(id)
.switchIfEmpty(Mono.error(new BusinessException("用户不存在")))
.onErrorMap(SQLException.class,
e -> new BusinessException("数据库查询失败", e))
.onErrorMap(TimeoutException.class,
e -> new BusinessException("服务调用超时,请稍后重试", e));
也可链式调用多个 onErrorMap,但推荐合并到一个中以提升可读性:
React 与 Next.js 性能优化指南,源自 Vercel 工程团队。适用于编写、审查或重构 React/Next.js 代码时使用。
.onErrorMap(throwable -> {
if (throwable instanceof SQLException) {
return new BusinessException("数据访问异常", throwable);
} else if (throwable instanceof IllegalArgumentException) {
return new ValidationException("参数校验失败", throwable);
}
return throwable; // 不匹配则透传原异常
});
结合上下文信息丰富业务异常
单纯类型匹配有时不够,可在 map 过程中注入请求 ID、用户 ID 等上下文,让异常更具诊断价值:
String userId = "U12345";
Mono.just(userId)
.flatMap(id -> apiClient.fetchProfile(id))
.onErrorMap(WebClientResponseException.class, e -> {
String detail = String.format("调用用户资料接口失败 [userId=%s, status=%d]",
userId, e.getRawStatusCode());
return new ExternalServiceException(detail, e);
});
注意:确保上下文变量在 lambda 中是 effectively final,避免意外闭包问题。
慎用:避免掩盖关键异常或破坏错误语义
不是所有异常都适合转译。以下情况应谨慎处理:
- RuntimeException 子类(如 NullPointerException) 通常是编程错误,不应静默转为业务异常
- Reactor 自身异常(如 MissingBackpressureException) 属于流控问题,需修复逻辑而非包装
- 已由下游统一兜底的异常,重复转译可能导致日志冗余或处理逻辑混乱
建议配合日志记录,尤其在转译前后打印原始异常堆栈,便于问题追踪。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










