papsign / Ktor-OpenAPI-Generator

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

Proper handling of library generated errors #29

Open Wicpar opened 4 years ago

Wicpar commented 4 years ago

Creating this because of #28 Currently there is no system to handle errors that occurred during runtime with this library. Instead i opted to use default values when parsing fails as it has best risk/effort ratio of the low effort options.

But now comes the time to implement it properly.

What it should do:

Wicpar commented 4 years ago

I am open to suggestions.

The basic idea would be like this:

@FallbackHandler(DefaultExceptionHandlerObject::class)
class KtorOpenAPIGenException(val errors: List<KtorOpenAPIGenError>): Exception("Relevant human readable version")

data class KtorOpenAPIGenError(val origin: KClass<*>, val what: String, val why: String, val where: String)

// example

KtorOpenAPIGenError(PrimitiveParser::class, "Could not parse parameter", "Bad format, should be an int", "theParameterName")

Ideally there would be hints as to what the value should be beyond just the type, like if it is annotated by @Min and @Max it should reflect that if possible. But i haven't thought that through yet.

stefan-cross commented 3 years ago

In a similar vein, how does one handle parsing requests types. Previously I would assign and type cast the incoming request in the body of route that would allow me to handle parsing issues e.g.

try{
val fooRequest = call.receive<FooRequest>()
...
 } catch (e : Exception) {
            e.printStackTrace()
                    when(e) {
                        is MissingKotlinParameterException, is JsonParseException -> {
                            this.pipeline.call.respond(HttpStatusCode.BadRequest)
                        }
                        else -> this.pipeline.call.respond(HttpStatusCode.InternalServerError)
                    }
                }        

However this now appears to be out of my control, any suggestions on how I could handle the parsing of requests?

stefan-cross commented 3 years ago

regarding the above 👆

Ignore me, i had overlooked your examples, for the benefit of others though here was how to capture potential parsing of request types...

data class Error<P>(val id: String, val payload: P)

throws(HttpStatusCode.BadRequest, Error::class, ({e: MissingKotlinParameterException -> Error("Your error", "and more details..")})) {
            route("/foo").post(....

Happy to help contribute on this project as its very useful, perhaps I can help with the docs?

Wicpar commented 3 years ago

Any help is welcome, especially with the docs :)