Flux.error return 200 http 代码即使抛出异常
Flux.error return 200 http code even if exception is thrown
我使用 spring-boot (v2 M3) 和 spring-webflux 开发一个项目。
在编写功能代码时,我发现我的微服务 returns 向我发送了一个 Http 200 状态代码,同时不断返回错误。
所以,我做了一个简单的测试:
我创建了一个简单的控制器
@RestController
@RequestMapping(value = "/test")
public class TestController {
@GetMapping(value = "/errors")
public Flux<Object> getErrors() {
return Flux.error(new RuntimeException("test"));
}
}
使用简单的异常处理程序:
@ControllerAdvice
public class TestExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(TestExceptionHandler.class);
@ExceptionHandler(value = { RuntimeException.class })
public ResponseEntity<String> handleServerError(final RuntimeException e) {
LOGGER.error(e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
}
然后我在集成测试中使用 webTestClient 测试了结果:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource("classpath:test.properties")
public class TestErrorsIT {
@Autowired
private WebTestClient webTestClient;
@Test
public void getErrors() {
this.webTestClient.get().uri("/test/errors").accept(MediaType.APPLICATION_STREAM_JSON).exchange().expectStatus()
.is5xxServerError();
}
}
结果,我的测试失败了,因为我的控制器 returns 错误通量 returns 200 状态代码而不是 503 状态代码(异常日志 "test" 很好在我的控制台中跟踪)。你知道为什么吗?
java.lang.AssertionError: Range for response status value 200
expected: but was:
GET http://localhost:54432/test/errors
WebTestClient-Request-Id: [1]
Accept: [application/stream+json]
没有内容
< 200 OK < 内容类型:[application/stream+json] <
传输编码:[分块] <日期:[2017 年 11 月 3 日,星期五 09:42:53 GMT]
内容尚不可用
在这种情况下,应用程序依赖于 spring-cloud-starter-eureka
,它本身依赖于 spring-boot-starter-web
。
将 spring-boot-starter-web
添加到 Spring 引导应用程序会将其变成 Spring MVC 应用程序,这解释了此行为。
我使用 spring-boot (v2 M3) 和 spring-webflux 开发一个项目。 在编写功能代码时,我发现我的微服务 returns 向我发送了一个 Http 200 状态代码,同时不断返回错误。
所以,我做了一个简单的测试: 我创建了一个简单的控制器
@RestController
@RequestMapping(value = "/test")
public class TestController {
@GetMapping(value = "/errors")
public Flux<Object> getErrors() {
return Flux.error(new RuntimeException("test"));
}
}
使用简单的异常处理程序:
@ControllerAdvice
public class TestExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(TestExceptionHandler.class);
@ExceptionHandler(value = { RuntimeException.class })
public ResponseEntity<String> handleServerError(final RuntimeException e) {
LOGGER.error(e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
}
然后我在集成测试中使用 webTestClient 测试了结果:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource("classpath:test.properties")
public class TestErrorsIT {
@Autowired
private WebTestClient webTestClient;
@Test
public void getErrors() {
this.webTestClient.get().uri("/test/errors").accept(MediaType.APPLICATION_STREAM_JSON).exchange().expectStatus()
.is5xxServerError();
}
}
结果,我的测试失败了,因为我的控制器 returns 错误通量 returns 200 状态代码而不是 503 状态代码(异常日志 "test" 很好在我的控制台中跟踪)。你知道为什么吗?
java.lang.AssertionError: Range for response status value 200 expected: but was:
GET http://localhost:54432/test/errors WebTestClient-Request-Id: [1] Accept: [application/stream+json]
没有内容
< 200 OK < 内容类型:[application/stream+json] < 传输编码:[分块] <日期:[2017 年 11 月 3 日,星期五 09:42:53 GMT]
内容尚不可用
在这种情况下,应用程序依赖于 spring-cloud-starter-eureka
,它本身依赖于 spring-boot-starter-web
。
将 spring-boot-starter-web
添加到 Spring 引导应用程序会将其变成 Spring MVC 应用程序,这解释了此行为。