papsign / Ktor-OpenAPI-Generator

Ktor OpenAPI/Swagger 3 Generator
Apache License 2.0
241 stars 42 forks source link

route(..).throws(...) eats stack trace #71

Closed brizzbuzz closed 3 years ago

brizzbuzz commented 4 years ago

Hey, project is really cool, just starting to dig into it... leaps and bounds better than my original plan of having to do hand rolled annotation + processing. One issue I'm running into is that it seems that

apiRouting {
  route("/example").throws(exampleError)

will eat the underlying stack trace, and simply output something similar to

ktor.application - 500 Internal Server Error: POST - /example 

Obvious this isn't ideal for a variety of reasons 😄

Wicpar commented 4 years ago

that is odd, can you provide a minimal pieceof code that can reproduce it ?

brizzbuzz commented 4 years ago

Sure thing... I'll adapt it from the app I'm working on... so let's say I have

fun Application.healthModule() {
  routing {
    health()
  }
}

fun Routing.health() {
  apiRouting {
    route("/") {
      tag(TagFactory.generateTag("System", "System monitoring endpoints")) {
        get<Unit, HealthCheck>(
          info(description = "Health Check Endpoint", summary = "Health Check"),
          example = HealthCheck(alive = true)
        ) {
          // respond(HealthCheck(alive = true))
          throw NotImplementedError("MEH")
        }
      }
    }
  }
}

when I run curl localhost:8080 I get the expected error, with corresponding stack trace

2020-08-18 20:45:00.294 [nioEventLoopGroup-4-1] ERROR ktor.application - Unhandled: GET - /
kotlin.NotImplementedError: MEH
    at org.leafygreens.backbone.generator.controllers.HealthControllerKt$health$1$1$1$1.invokeSuspend(HealthController.kt:25)
    at org.leafygreens.backbone.generator.controllers.HealthControllerKt$health$1$1$1$1.invoke(HealthController.kt)
    at com.papsign.ktor.openapigen.route.path.normal.NormalOpenAPIRoute$handle$2.invokeSuspend(NormalOpenAPIRoute.kt:37)
    at com.papsign.ktor.openapigen.route.path.normal.NormalOpenAPIRoute$handle$2.invoke(NormalOpenAPIRoute.kt)
    at com.papsign.ktor.openapigen.route.OpenAPIRoute$handle$$inlined$apply$lambda$1$1.invokeSuspend(OpenAPIRoute.kt:65)
    at com.papsign.ktor.openapigen.route.OpenAPIRoute$handle$$inlined$apply$lambda$1$1.invoke(OpenAPIRoute.kt)
    at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:318)
    at io.ktor.util.pipeline.SuspendFunctionGun.proceed(PipelineContext.kt:163)
    at io.ktor.util.pipeline.SuspendFunctionGun.execute(PipelineContext.kt:183)
    at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:27)
    at io.ktor.routing.Routing.executeResult(Routing.kt:147)

However, when I attach throws() like so

val nie = APIException.apiException<NotImplementedError, ExceptionResponse>(HttpStatusCode.InternalServerError, example = ExceptionResponse(message = "Bad things happened"))

fun Routing.health() {
  apiRouting {
    route("/").throws(nie) {
      tag(TagFactory.generateTag("System", "System monitoring endpoints")) {
        get<Unit, HealthCheck>(
          info(description = "Health Check Endpoint", summary = "Health Check"),
          example = HealthCheck(alive = true)
        ) {
          // respond(HealthCheck(alive = true))
          throw NotImplementedError("MEH")
        }
      }
    }
  }
}

Then, when I run curl localhost:8080, the only output is

2020-08-18 20:52:17.442 [nioEventLoopGroup-4-2] INFO  ktor.application - 500 Internal Server Error: GET - /
hamza-maqsood commented 3 years ago

I am having the same issue, anyone knows a workaround?

Wicpar commented 3 years ago

It actually works properly, the throws catches the exception and handles it as a response as it is no longer considered an error. You can print it in the handler if you need to, there is a parameter that accepts a transform function in apiException

brizzbuzz commented 3 years ago

Oh I had forgotten about this ticket, I'm going to close it since this is expected behavior