1

我有一个简单的 Micronaut 控制器,它有 2 个类似的GET方法,它们返回不同的反应类型。

@Controller
public class MyController {
    
    @Get(uri = "/a", produces = MediaType.APPLICATION_JSON_STREAM)
    public Flux<MyPojo> getA() {
        return Flux.just("Hi")
                .flatMap(s -> Mono.error(new HttpStatusException(HttpStatus.BAD_REQUEST, s)))
                .map(o -> new MyPojo());
    }

    @Get(uri = "/b", produces = MediaType.APPLICATION_JSON_STREAM)
    public Mono<MyPojo> getB() {
        return Mono.just("Hi")
                .flatMap(s -> Mono.error(new HttpStatusException(HttpStatus.BAD_REQUEST, s)))
                .map(o -> new MyPojo());
    }
                
}

现在,如果我调用端点,我将获得带有默认错误表示的/bHTTP 400,这是理想且完美的。io.micronaut.http.hateoas.JsonErrorio.micronaut.http.server.exceptions.HttpStatusHandler

{
  "message": "Bad Request",
  "_embedded": {
    "errors": [
      {
        "message": "Hi"
      }
    ]
  },
  "_links": {
    "self": {
      "href": "/b",
      "templated": false
    }
  }
}

但是,如果我调用端点,/a我会得到没有任何正文的 HTTP 500 错误。日志文件报告以下错误:

2022-01-12 00:45:31.385 ERROR [default-nioEventLoopGroup-2-2] i.m.h.netty.stream.HttpStreamsHandler    : Error occurred writing stream response: Hi
io.micronaut.http.exceptions.HttpStatusException: Hi
    at com.example.MyController.lambda$getA$6(MyController.java:199)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:386)
    at io.micronaut.reactive.reactor.instrument.ReactorSubscriber.onNext(ReactorSubscriber.java:57)
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371)
    at io.micronaut.reactive.reactor.instrument.ReactorSubscriber.onSubscribe(ReactorSubscriber.java:50)
    at reactor.core.publisher.FluxJust.subscribe(FluxJust.java:68)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8468)
    ...

这似乎是正确的......

JsonError问题是 -在端点的情况下如何获得正确的 HTTP 代码(400)和默认错误表示( ) /a

4

1 回答 1

0

端点指示流式传输,/a因为您返回的是非单一发布者类型。流式响应的处理方式不同,遇到错误时我们切换到写入响应的模式。此时返回创建另一个响应是不可行的,因为一个 OK 响应已经通过 Netty 管道发送。

https://github.com/micronaut-projects/micronaut-core/issues/5581

于 2022-01-13T06:08:48.093 回答