perwendel / spark

A simple expressive web framework for java. Spark has a kotlin DSL https://github.com/perwendel/spark-kotlin
Apache License 2.0
9.65k stars 1.56k forks source link

java.lang.Error causes request to be retried #857

Open plombardi89 opened 7 years ago

plombardi89 commented 7 years ago

Sorry this is in Kotlin, but I can convert to Java if necessary...

If an Error or subclass of Error is thrown in a Route handler then the request is retried. I have a handler like this:

      post   ("/bodydupe", acceptJson, Route {
        req, res ->

        println("BODY = ${req.body()}")
        throw java.lang.Error("wtfsauce")

      }, jsonifier)

My logs look like this:

BODY = {  ... JSON passed in... }
BODY = 

Using a curl request such as

curl -H 'Accept: application/json' -X POST -d '@somedata.json' localhost:7000/api/bodydupe

Ran into this because Kotlin extends Error in a number of cases, for example, NotImplementedError which is thrown when you use a `TODO("Some Message") here function.

tipsy commented 7 years ago

The exception mapper only catches Exceptions, so that makes sense. I'm surprised Kotlin throws errors though, isn't that generally for critical/non recoverable errors (out of memory, stack overflow), not common exceptions? Do you have any examples of when Kotlin throws Errors, other than NotImplementedError (which sort-of makes sense). I suppose we could catch Throwable, but I'm not sure it would be good.

plombardi89 commented 7 years ago

@tipsy I am primarily concerned that it retries the request. I would at least expect Spark to catch the Error and not retry the request. What if someone has logic in there that mutates something?

I'm not sure I see the harm in exposing a handler for Throwable either. Plenty of frameworks do this.

plombardi89 commented 7 years ago

I have created a reproducible project for this that shows the bug in both Kotlin and Java based Spark servers: https://github.com/plombardi89/sparkjava-issue-857

curl -X POST -d 'Hello!' localhost:5000/
curl -X POST -d 'Hello!' localhost:5001/

The logs will look like this:

Java version running on: 5000
BODY (Java) => Hello!
BODY (Java) => 

Kotlin version running on: 5001
BODY (Kotlin) => Hello!
BODY (Kotlin) => 
tipsy commented 7 years ago

I'm sorry, I read your issue poorly. The request is not supposed to be retried. Thanks for your example project, I will have a look when I get back from vacation next week.

mlitcher commented 7 years ago

Looks like Jetty is doing an error dispatch the second time through (DispatcherType.ERROR).

plombardi89 commented 7 years ago

Still occurring and very annoying :(

rodrigomanhaes commented 5 years ago

Same error just occurred here.