RestTemplate捕获HttpServerErrorException后如何正确抛出供前端获取字段
解决方案
HttpServerErrorException提供了多参数重载的构造方法,你可以根据需求选择保留原始下游服务的错误信息,或者自定义返回给前端的结构化内容,以下是两种常用实现方案:
方案1:保留原始错误信息+追加业务上下文
适合需要把下游服务的完整错误信息透传给前端,同时补充当前请求的业务参数的场景:
catch (HttpServerErrorException e) { // 拼接自定义业务提示信息 String errorMsg = String.format( "获取图书数据失败,图书ID:%s,作者:%s,下游服务状态码:%s,下游响应内容:%s", bookId, author.name, e.getStatusCode(), e.getResponseBodyAsString() ); // 打印日志时传入原始异常,保留堆栈信息方便排查 LOGGER.error(errorMsg, e); // 构造并抛出新的异常,保留原始的状态码、响应头、响应体,同时替换提示文本 throw new HttpServerErrorException( e.getStatusCode(), errorMsg, e.getResponseHeaders(), e.getResponseBodyAsByteArray(), e.getResponseCharset() ); }
方案2:自定义结构化响应返回给前端
适合需要给前端返回统一格式的JSON错误信息,不需要透传下游原始响应的场景:
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.HttpStatus; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; // 捕获块内逻辑 catch (HttpServerErrorException e) { // 构造结构化错误内容 Map<String, Object> errorResult = new HashMap<>(); errorResult.put("code", 50001); // 自定义业务错误码 errorResult.put("message", String.format("获取图书信息失败,图书ID:%s,作者:%s", bookId, author.name)); errorResult.put("requestId", "当前请求的链路ID"); // 可追加链路追踪等扩展字段 // 把错误对象转成JSON字节数组 ObjectMapper objectMapper = new ObjectMapper(); byte[] respBody = objectMapper.writeValueAsBytes(errorResult); LOGGER.error("获取图书信息异常 bookId:{}, author:{}", bookId, author.name, e); // 构造自定义异常抛出 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); throw new HttpServerErrorException( HttpStatus.INTERNAL_SERVER_ERROR, "业务处理失败", headers, respBody, StandardCharsets.UTF_8 ); }
- 补充说明:
- 如果项目中配置了
@RestControllerAdvice全局异常处理器,也可以自定义业务异常抛出,在全局处理器中统一封装响应格式,适配性更强 - 生产环境建议敏感信息不要返回给前端,比如下游服务的内部地址、未脱敏的原始响应内容等
- 如果项目中配置了
内容的提问来源于stack exchange,提问作者user9347049
相关产品推荐
相关产品推荐

