ktorio / ktor

Framework for quickly creating connected applications in Kotlin with minimal effort
https://ktor.io
Apache License 2.0
12.53k stars 1.02k forks source link

Can't install statuspages under route (or other ApplicationCallPipeline) #193

Closed mathiasbn closed 2 years ago

mathiasbn commented 6 years ago

Given that ktor now has Introduce send and receive pipelines on all levels(commit msg). Wouldn't this test make sense (it fails):

   @Test
    fun testStatusMapping2() {
        withTestApplication {
            application.routing{
                route("/foo") {
                    install(StatusPages) {
                        statusFile(HttpStatusCode.NotFound, filePattern = "error#.html")
                    }
                    intercept(ApplicationCallPipeline.Call) {
                        call.respond(HttpStatusCode.NotFound)
                    }
                }
            }
            handleRequest(HttpMethod.Get, "/foo").let { call ->
                assertEquals("<html><body>error 404</body></html>", call.response.content)
            }
        }
    }

It's a copy/paste of testStatusMapping test, but with statuspages installed under a route pipeline (edited)

cy6erGn0m commented 6 years ago

See testStatusMappingWithRoutes: it is passing now

orangy commented 6 years ago

Is it fixed now?

mathiasbn commented 6 years ago

I'm not working with that project anymore, but I will ping the guys

spand commented 6 years ago

The test passes because it explicitly returns 404. Same with the internal server error. If I am not mistaken then StatusPage installed on Application will also handle the implicit ones also (ie. page not founds if not routed). Consider the following test:

@Test
fun testStatusMappingWithRoutes1() {
    withTestApplication {
        application.install(StatusPages) {
            status(HttpStatusCode.NotFound) { call.respondText("Not Found Application", status = HttpStatusCode.NotFound) }
            exception<Throwable> { call.respondText("Internal Server Error Application", status = HttpStatusCode.InternalServerError) }
        }

        application.routing {
            route("/foo") {
                route("/wee") {
                    handle {
                        throw Exception()
                    }
                }
                install(StatusPages) {
                    status(HttpStatusCode.NotFound) { call.respondText("Not Found Route", status = HttpStatusCode.NotFound) }
                    exception<Throwable> { call.respondText("Internal Server Error Route", status = HttpStatusCode.InternalServerError) }
                }
            }
        }
        listOf("/foo", "/foo/1").forEach { path ->
            handleRequest(HttpMethod.Get, path).let { call ->
                assertEquals(HttpStatusCode.NotFound, call.response.status())
                assertEquals("Not Found Route", call.response.content)
            }
        }
        handleRequest(HttpMethod.Get, "/foo/wee").let { call ->
            assertEquals(HttpStatusCode.InternalServerError, call.response.status())
            assertEquals("Internal Server Error Route", call.response.content)
        }
    }
}

It currently fails with a null statuscode but in a real embedded server I would except it to fail with "Not Found Application" != "Not Found Route".

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity.

oleg-larshin commented 3 years ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

e5l commented 2 years ago

Obsolete with new testing API in 2.0.0