Spring Cloud Gateway返回HTML错误而非转发后端服务错误
Spring Cloud Gateway MVC 返回500错误(后端返回409时)排查解决
问题出在哪
当后端返回409这类错误状态码时,基于Tomcat的Spring Cloud Gateway MVC会触发默认错误处理机制,自动把请求转发到/error路径。但你的网关配置里,前端路由是Path=/**,这个/error请求会被转发到前端SPA,可前端根本没有这个路径,于是出现FileNotFoundException,最终网关返回500状态码和HTML格式的错误页面,而不是直接透传后端的409错误。
怎么解决
1. 自定义网关错误处理逻辑,别再转发到前端
写一个自定义的ErrorController,让网关自己处理错误请求,直接返回JSON格式的错误响应:
@RestController @RequestMapping("/error") public class CustomErrorController implements ErrorController { @RequestMapping public ResponseEntity<Map<String, Object>> handleError(HttpServletRequest request) { Map<String, Object> errorDetails = new HashMap<>(); // 获取原始错误状态码 Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); // 获取原始错误信息 String errorMessage = (String) request.getAttribute(RequestDispatcher.ERROR_MESSAGE); if (statusCode != null) { errorDetails.put("status", statusCode); errorDetails.put("message", errorMessage != null ? errorMessage : HttpStatus.valueOf(statusCode).getReasonPhrase()); return new ResponseEntity<>(errorDetails, HttpStatus.valueOf(statusCode)); } errorDetails.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value()); errorDetails.put("message", "Unexpected error occurred"); return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR); } }
2. 加个专属路由处理错误请求,优先级要比前端路由高
在网关配置里新增一个路由,确保/error请求被网关自己接住,不会转到前端:
# 错误处理路由(放在前端路由前面,优先级更高) spring.cloud.gateway.mvc.routes[1].id=error-handler spring.cloud.gateway.mvc.routes[1].uri=forward:/error spring.cloud.gateway.mvc.routes[1].predicates=Path=/error # 原API路由保持不变 spring.cloud.gateway.mvc.routes[0].id=api spring.cloud.gateway.mvc.routes[0].uri=${backend-uri} spring.cloud.gateway.mvc.routes[0].predicates[0]=Path=/api/** spring.cloud.gateway.mvc.routes[0].filters[0].name=DedupeResponseHeader spring.cloud.gateway.mvc.routes[0].filters[0].args[name]=Access-Control-Allow-Credentials Access-Control-Allow-Origin spring.cloud.gateway.mvc.routes[0].filters[1].name=TokenRelay # 前端路由保持不变 spring.cloud.gateway.mvc.routes[2].id=frontend spring.cloud.gateway.mvc.routes[2].uri=${frontend-uri} spring.cloud.gateway.mvc.routes[2].predicates=Path=/**
3. 关掉Tomcat的白标错误页面(可选)
加个配置关闭默认的白标错误页面,保证自定义的错误处理能生效:
server.error.whitelabel.enabled=false
验证
配置完之后,再测试后端返回409的场景,网关会直接返回JSON格式的409响应,内容包含错误状态码和信息,不会再出现500错误和HTML响应了。
内容的提问来源于stack exchange,提问作者Mendi S
相关产品推荐
相关产品推荐

