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

Spring Boot服务间REST调用异常信息无法传递,如何获取原错误消息?

如何让Spring Boot调用方捕获被调用服务的原异常消息

这个问题我之前也碰到过,核心原因其实是被调用服务没有把异常消息正确传递到HTTP响应里,而调用方又没从响应体里提取真正的错误内容,才拿到了那种笼统的I/O错误提示。咱们一步步解决:

第一步:先让被调用服务把错误消息返回给调用方

默认情况下,Spring Boot如果抛出未处理的RuntimeException,会返回一个500错误,但这个响应里的消息不会直接是你抛出的"Already modified"——要么是默认的错误页面(HTML),要么是包含通用字段的JSON,但原消息可能没被正确暴露出来。所以得让被调用服务主动把异常消息放到HTTP响应体中:

方法1:用全局异常处理器(推荐)

在被调用服务里写一个全局异常处理类,捕获RuntimeException并返回带消息的响应:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> handleRuntimeException(RuntimeException e) {
        // 选一个合适的状态码,比如409(冲突)比500更贴合"已被修改"的场景
        return ResponseEntity.status(HttpStatus.CONFLICT).body(e.getMessage());
    }
}

方法2:自定义异常+@ResponseStatus

如果想更规范,可以自定义一个异常类,用注解指定状态码:

@ResponseStatus(HttpStatus.CONFLICT) // 返回409状态码
public class AlreadyModifiedException extends RuntimeException {
    public AlreadyModifiedException(String message) {
        super(message);
    }
}

然后被调用服务里抛出这个自定义异常:

throw new AlreadyModifiedException("Already modified");

这种方式下,Spring会自动生成包含原消息的JSON响应(结构类似{"timestamp":"...","status":409,"error":"Conflict","message":"Already modified","path":"/xxx"})。

第二步:调用方从响应体提取原错误消息

现在调用方的问题是,RestClientResponseException.getMessage()返回的是封装了请求URL和状态的通用提示,比如"I/O error on PUT request for ...",但真正的错误消息在响应体里。所以要修改调用方的catch逻辑:

情况1:被调用方返回纯文本消息(对应方法1)

直接读取响应体字符串:

try {
    response = restTemplate.exchange(urlModifyAttributes, HttpMethod.PUT, new HttpEntity<>(attributesMap, headerMap), parameterizedTypeReference, uriVars);
    return response.getBody();
} catch (RestClientResponseException e) {
    // 读取响应体里的原错误消息
    String originalErrorMessage = e.getResponseBodyAsString();
    log.error("Modify attributes failed. Status code: {}, Original error: {}", e.getStatusCode(), originalErrorMessage, e);
    throw new RuntimeException(originalErrorMessage);
} catch (Exception e) {
    log.error("Modify attributes failed. Error: {}", e.getMessage(), e);
    throw new RuntimeException(e.getMessage());
}

情况2:被调用方返回JSON格式错误(对应方法2)

需要解析JSON拿到message字段,先写一个对应错误结构的POJO:

class ErrorResponse {
    private String message;

    // getter和setter
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

然后在catch块里解析:

catch (RestClientResponseException e) {
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        ErrorResponse errorResponse = objectMapper.readValue(e.getResponseBodyAsString(), ErrorResponse.class);
        String originalErrorMessage = errorResponse.getMessage();
        log.error("Modify attributes failed. Status code: {}, Original error: {}", e.getStatusCode(), originalErrorMessage, e);
        throw new RuntimeException(originalErrorMessage);
    } catch (JsonProcessingException ex) {
        // 解析失败时降级处理
        log.error("Failed to parse error response", ex);
        throw new RuntimeException("Modify attributes failed", e);
    }
}

这样调整后,调用方就能拿到被调用服务抛出的"Already modified"原消息了~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:21:32