代码之家  ›  专栏  ›  技术社区  ›  Sergey Prokofiev

Micronaut不返回Flux返回类型的默认HTTP错误表示

  •  0
  • Sergey Prokofiev  · 技术社区  · 3 年前

    我有一个简单的Micronaut控制器,有两个类似的 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());
        }
                    
    }
    

    现在,如果我调用端点 /b 我将获得具有默认错误表示的HTTP 400 io.micronaut.http.hateoas.JsonError 由提供 io.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)
        ...
    

    这似乎是正确的。。。

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

    0 回复  |  直到 3 年前
        1
  •  1
  •   James Kleeh    3 年前

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

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