在Apollo/Spring响应式应用中实现自定义异常向前端传递
解决方案:在响应式Spring Boot GraphQL中传递自定义异常信息到前端
要让前端获取自定义异常中的有效信息,核心是通过自定义GraphQL异常处理器将异常信息序列化到响应的extensions字段中,避免Spring GraphQL默认的通用错误包装。以下是具体实现步骤:
1. 定义自定义业务异常
无需继承GraphQLException,使用普通RuntimeException即可,保留需要传递给前端的字段:
public class MyCustomException extends RuntimeException { private final String userInfo; public MyCustomException(String message, String userInfo) { super(message); this.userInfo = userInfo; } public String getUserInfo() { return userInfo; } }
2. 创建全局GraphQL异常处理器
通过@GraphQlExceptionHandler捕获自定义异常,将其转换为包含自定义信息的GraphQLError,并将业务字段放入extensions:
@ControllerAdvice public class GlobalGraphQLExceptionHandler { @GraphQlExceptionHandler(MyCustomException.class) public GraphQLError handleCustomException(MyCustomException ex, @GraphQlContext GraphQlContext context) { // 获取GraphQL请求的位置和路径信息(可选,用于定位错误位置) List<SourceLocation> locations = context.get(SourceLocations.class).orElse(Collections.emptyList()); List<Object> path = context.get(ExecutionPath.class) .map(ExecutionPath::toList) .orElse(Collections.emptyList()); // 构建自定义GraphQLError return GraphQLError.newError() .message(ex.getMessage()) .locations(locations) .path(path) .errorType(() -> "CUSTOM_BUSINESS_ERROR") // 自定义错误类型标识 .extension("userInfo", ex.getUserInfo()) // 传递给前端的业务信息 .build(); } }
3. 控制器中抛出自定义异常
保持原有业务逻辑,直接抛出定义好的异常即可:
@MutationMapping public Mono<Customer> simulateAnError() { return Mono.error(new MyCustomException("My custom Exception", "Useful information for the front end")); }
前端收到的响应示例
此时前端会收到包含自定义信息的错误响应:
{ "errors": [ { "message": "My custom Exception", "locations": [ { "line": 2, "column": 3 } ], "path": [ "simulateAnError" ], "extensions": { "errorType": "CUSTOM_BUSINESS_ERROR", "userInfo": "Useful information for the front end" } } ], "data": { "simulateAnError": null } }
关键说明
- 避免直接继承
GraphQLException:Spring GraphQL默认会包装此类异常,丢失自定义字段,通过全局处理器手动转换更可控。 - 生产环境注意事项:关闭
spring.graphql.servlet.exception-handling.debug配置,避免泄露敏感信息;仅将用户需要的业务字段放入extensions。
内容的提问来源于stack exchange,提问作者Oliver Watkins
相关产品推荐
相关产品推荐

