micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.09k stars 1.07k forks source link

"No serializer found for class io.netty.handler.codec.http.HttpResponseStatus" when returning HttpClientResponseException in response #6639

Closed jacekgajek closed 2 years ago

jacekgajek commented 2 years ago

Expected Behavior

HttpClientResponseException serialized to JSON in response

Actual Behaviour

Response:

{
  "message": "Internal Server Error",
  "logref": null,
  "path": null,
  "_links": {
    "self": {
      "href": "/test",
      "templated": false,
      "profile": null,
      "deprecation": null,
      "title": null,
      "hreflang": null,
      "type": null,
      "name": null
    }
  },
  "_embedded": {
    "errors": [
      {
        "message": "Internal Server Error: Error encoding object [io.micronaut.http.client.exceptions.HttpClientResponseException: asd] to JSON: No serializer found for class io.netty.handler.codec.http.cookie.ServerCookieEncoder and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: io.micronaut.http.client.exceptions.HttpClientResponseException[\"response\"]->io.micronaut.http.netty.NettyMutableHttpResponse[\"serverCookieEncoder\"])",
        "logref": null,
        "path": null,
        "_links": {},
        "_embedded": {}
      }
    ]
  }
}

"Internal Server Error: Error encoding object [io.micronaut.http.client.exceptions.HttpClientResponseException: asd] to JSON: No serializer found for class io.netty.handler.codec.http.cookie.ServerCookieEncoder and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: io.micronaut.http.client.exceptions.HttpClientResponseException[\"response\"]->io.micronaut.http.netty.NettyMutableHttpResponse[\"serverCookieEncoder\"])",

Steps To Reproduce

Launch a GET request to an endpoint which returns a HttpClientResponseException, for example

    @Get(uri = "/test")
    fun test(): HttpClientResponseException = HttpClientResponseException("asd", HttpResponse.ok("ok"))

Environment Information

Ubuntu 20.04.3 LTS openjdk-15.0.1

    implementation("io.micronaut:micronaut-runtime:3.2.0")
    implementation("io.micronaut.kotlin:micronaut-kotlin-extension-functions:3.0.0")
    implementation("io.micronaut.kotlin:micronaut-kotlin-runtime:3.0.0")
    implementation("io.micronaut:micronaut-management:3.2.0")
    implementation("io.micronaut.gcp:micronaut-gcp-logging:4.0.0")
    implementation("io.micronaut.rxjava2:micronaut-rxjava2:1.1.0")
    implementation("io.micronaut:micronaut-http-client:3.2.0")
    implementation("io.micronaut.redis:micronaut-redis-lettuce")
    implementation("io.micronaut.cache:micronaut-cache-core")
    implementation("io.micronaut.jmx:micronaut-jmx:3.0.0")
    implementation("io.micronaut.openapi:micronaut-openapi:3.2.0")

    annotationProcessor("io.micronaut.openapi:micronaut-openapi:3.2.0")
    annotationProcessor("io.micronaut:micronaut-http-validation:3.1.4")
    annotationProcessor("io.micronaut:micronaut-management:3.2.0")

Example Application

No response

Version

3.2.0

yawkat commented 2 years ago

You're supposed to throw the exception, not return it directly

jacekgajek commented 2 years ago

Yes I know that. I have a global exception handler which returns a thrown exception, this is just a simplified example. It works great for most of exception and provides very useful info about internal error (the REST service is for internal use and it's OK to expose these details)

yawkat commented 2 years ago

So you actually want the full Throwable serialized, including stack trace and such?

The exceptions from the micronaut framework do not generally support serialization. If they do, it's by accident. In my opinion we shouldn't either, since serializing throwables is generally a dangerous practice that could lead to information leaks (though it might not in your case).

Consider using micronaut-problem-json instead. It has support for serializing stack traces if configured to do so, and if the exception is a ThrowableProblem.

graemerocher commented 2 years ago

Indeed serializing exceptions directly can result in leaking information which could lead to security vulnerabilities so this is not a good idea.

jacekgajek commented 2 years ago

Thanks for a fast response and explanation. Have a nice day :)