Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server-test-host: Rethrown exception in StatusPages exception handler fails test #1701

Open
juggernaut0 opened this issue Mar 4, 2020 · 5 comments
Labels

Comments

@juggernaut0
Copy link

Ktor Version and Engine Used (client or server and name)
Using ktor server 1.3.1, with ktor-server-test-host

Describe the bug
When using the StatusPages feature to handle exceptions, a rethrowing the exception will bubble out to the test and cause a failure even if it was successfully handled with a call.respond. Rethrowing exceptions is suggested as a way to log caught exceptions in the documentation: https://ktor.io/servers/features/status-pages.html#logging-exceptions

To Reproduce

    @Test
    fun test() {
        open class MyException : RuntimeException()

        withTestApplication({
            install(StatusPages) {
                exception<MyException> {
                    call.respond(HttpStatusCode.UnprocessableEntity, it.toString())
                    throw it // Comment out this line to pass test, but not log exception
                }
            }
            routing {
                get("/") {
                    throw MyException()
                }
            }
        }) {
            with(handleRequest {
                method = HttpMethod.Get
                uri = "/"
            }) {
                assertEquals(HttpStatusCode.UnprocessableEntity, response.status())
            }
        }
    }

Expected behavior
I expect the above test to pass, and the exception to be logged as it would in a non-test application

@juggernaut0 juggernaut0 added the bug label Mar 4, 2020
@cy6erGn0m cy6erGn0m removed the bug label Mar 5, 2020
@cy6erGn0m
Copy link
Contributor

This is by design behaviour: uncaught exceptions are always treated as errors and should not occur.

@juggernaut0
Copy link
Author

Okay that makes sense. Perhaps a note should be added to the documentation about that.

@cab404
Copy link
Contributor

cab404 commented Apr 3, 2020

This is by design behaviour: uncaught exceptions are always treated as errors and should not occur.

As good as it sounds, that doesn't help us testing.
Is there any way of handling those exceptions (probably in routing?), so we can test error messages?

For now I plan to add wrap each lambda I give to routing into try-catch, but that's obviously a hack.

@e5l
Copy link
Member

e5l commented Jun 5, 2020

Hi @cab404, to do that you can add the pipeline interceptor and wrap the proceed method with a try catch block.

@e5l e5l added the question label Jun 5, 2020
@RyanGrif
Copy link
Contributor

RyanGrif commented Aug 10, 2020

Just encountered this myself, and found that you can also get around it by just logging the exception manually, rather than re-throwing it:

    @Test
    fun test() {
        val logger = KotlinLogging.logger {}

        open class MyException : RuntimeException()

        withTestApplication({
            install(StatusPages) {
                exception<MyException> {
                    logger.error(it)
                    call.respond(HttpStatusCode.UnprocessableEntity, it.toString())
                }
            }
            routing {
                get("/") {
                    throw MyException()
                }
            }
        }) {
            with(handleRequest {
                method = HttpMethod.Get
                uri = "/"
            }) {
                assertEquals(HttpStatusCode.UnprocessableEntity, response.status())
            }
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants