首页 > 解决方案 > Micronaut ExceptionHandler:使用状态码和正文创建 HttpResponse

问题描述

在我的 Micronaut 应用程序中,我定义了一个ExceptionHandler,它应该捕获WorkflowException并返回一个HttpResponse状态码为 412 并WorkflowExceptionVM作为正文的。

这是我当前的实现:

@Produces
@Singleton
@Requires(classes = [WorkflowException::class, ExceptionHandler::class])
class WorkflowExceptionHandler : ExceptionHandler<WorkflowException, HttpResponse<WorkflowExceptionVM>> {

    override fun handle(request: HttpRequest<Any>, exception: WorkflowException): HttpResponse<WorkflowExceptionVM> {
        return HttpResponse.status<WorkflowExceptionVM>(HttpStatus.PRECONDITION_FAILED)
                .body(WorkflowExceptionVM(exception.code))
    }
}

它使用正确的代码生成响应,但不包括正文。

这是我的测试:

@Test
fun `Should handle WorkflowException`() {
    val request = POST(THE_URL, THE_BODY).basicAuth("user", "password")
    val exception = shouldThrow<HttpClientResponseException>
        {client.toBlocking().exchange(request, MyEntity::class.java) }

    exception.response.code() shouldBe 412 // This works
    exception.response.body() // ERROR: this is null
}


如何将正文添加到响应中?

标签: kotlinmicronaut

解决方案


要获取错误正文,您需要使用 3 参数exchange方法,其中第 3 个参数是错误类型:https ://docs.micronaut.io/1.2.x/api/io/micronaut/http/client/DefaultHttpClient.html #exchange-io.micronaut.http.HttpRequest-io.micronaut.core.type.Argument-io.micronaut.core.type.Argument-

所以,你的代码应该是:

val exception = shouldThrow<HttpClientResponseException>
        {client.toBlocking().exchange(request, MyEntity::class.java, WorkflowExceptionVM::class.java) }

我不能 100% 确定这是否适用于 Kotlin,因为在 Java 中你需要将bodyTypeand包装errorTypeArgument. 如果它不起作用,请尝试:

val exception = shouldThrow<HttpClientResponseException>
        {client.toBlocking().exchange(request, Argument.of(MyEntity::class.java), Argument.of(WorkflowExceptionVM::class.java)) }

更新:从异常中提取主体使用exception.getResponse().getBody(WorkflowExceptionVM::class.java). 这将返回一个Optional,因此您可以检查主体是否存在并获取它并检查WorkflowExceptionVM.


推荐阅读