From cba36a864e593ead3a6c2cd20d2886981f434a59 Mon Sep 17 00:00:00 2001 From: david steinsland Date: Wed, 27 Nov 2024 20:52:16 +0100 Subject: [PATCH] =?UTF-8?q?setter=20kun=20error=20body=20with=20det=20ikke?= =?UTF-8?q?=20er=20body=20fra=20f=C3=B8r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../navikt/tbd_libs/naisful/NaisfulApp.kt | 31 +++++++++----- .../navikt/tbd_libs/naisful/NaisfulAppTest.kt | 40 ++++++++++++++----- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/naisful-app/src/main/kotlin/com/github/navikt/tbd_libs/naisful/NaisfulApp.kt b/naisful-app/src/main/kotlin/com/github/navikt/tbd_libs/naisful/NaisfulApp.kt index 96f0db3..13872d9 100644 --- a/naisful-app/src/main/kotlin/com/github/navikt/tbd_libs/naisful/NaisfulApp.kt +++ b/naisful-app/src/main/kotlin/com/github/navikt/tbd_libs/naisful/NaisfulApp.kt @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import io.ktor.events.* import io.ktor.http.* import io.ktor.http.HttpStatusCode.Companion.allStatusCodes +import io.ktor.http.content.OutgoingContent import io.ktor.serialization.jackson.* import io.ktor.server.application.* import io.ktor.server.cio.* @@ -314,16 +315,26 @@ fun StatusPagesConfig.defaultStatusPagesConfig() { )) } status(*allStatusCodes.filterNot { code -> code.isSuccess() }.toTypedArray()) { statusCode -> - if (content.contentLength == null) { - call.response.header("Content-Type", ContentType.Application.ProblemJson.toString()) - call.respond(statusCode, FeilResponse( - status = statusCode, - type = statusCode.toURI(call), - detail = statusCode.description, - instance = URI(call.request.uri), - callId = call.callId, - stacktrace = null - )) + /* exhaustive when-block so it will be compiler error if new types are added */ + when (content) { + is OutgoingContent.NoContent -> { + call.response.header("Content-Type", ContentType.Application.ProblemJson.toString()) + call.respond(statusCode, FeilResponse( + status = statusCode, + type = statusCode.toURI(call), + detail = statusCode.description, + instance = URI(call.request.uri), + callId = call.callId, + stacktrace = null + )) + } + is OutgoingContent.ByteArrayContent, + is OutgoingContent.ContentWrapper, + is OutgoingContent.ProtocolUpgrade, + is OutgoingContent.ReadChannelContent, + is OutgoingContent.WriteChannelContent -> { + /* do nothing */ + } } } } diff --git a/naisful-app/src/test/kotlin/com/github/navikt/tbd_libs/naisful/NaisfulAppTest.kt b/naisful-app/src/test/kotlin/com/github/navikt/tbd_libs/naisful/NaisfulAppTest.kt index c704088..ebdbf7e 100644 --- a/naisful-app/src/test/kotlin/com/github/navikt/tbd_libs/naisful/NaisfulAppTest.kt +++ b/naisful-app/src/test/kotlin/com/github/navikt/tbd_libs/naisful/NaisfulAppTest.kt @@ -108,27 +108,47 @@ class NaisfulAppTest { } @Test - fun `method not allowed`() { + fun `default error body`() { testApp( applicationModule = { routing { - get("/test") { + get("/test1") { call.respond(HttpStatusCode.OK) } + get("/test2") { + call.respond(HttpStatusCode.Conflict, "This is a body") + } + get("/test3") { + call.respond(HttpStatusCode.Forbidden, CustomResponse("Fault")) + } } } ) { - val response = post("/test") - val body = response.body() - assertEquals(ContentType.Application.ProblemJson, response.contentType()) - assertEquals(URI("urn:error:method_not_allowed"), body.type) - assertEquals(HttpStatusCode.MethodNotAllowed.description, body.title) - assertEquals(HttpStatusCode.MethodNotAllowed.value, body.status) - assertEquals(URI("/test"), body.instance) - assertEquals("Method Not Allowed", body.detail) + post("/test1").also { response -> + val body = response.body() + assertEquals(HttpStatusCode.MethodNotAllowed, response.status) + assertEquals(ContentType.Application.ProblemJson, response.contentType()) + assertEquals(URI("urn:error:method_not_allowed"), body.type) + assertEquals(HttpStatusCode.MethodNotAllowed.description, body.title) + assertEquals(HttpStatusCode.MethodNotAllowed.value, body.status) + assertEquals(URI("/test1"), body.instance) + assertEquals("Method Not Allowed", body.detail) + } + get("/test2").also { response -> + assertEquals(HttpStatusCode.Conflict, response.status) + assertEquals(ContentType.Text.Plain.withCharset(Charsets.UTF_8), response.contentType()) + assertEquals("This is a body", response.bodyAsText()) + } + get("/test3").also { response -> + assertEquals(HttpStatusCode.Forbidden, response.status) + assertEquals(ContentType.Application.Json.withCharset(Charsets.UTF_8), response.contentType()) + assertEquals("Fault", response.body().text) + } } } + private data class CustomResponse(val text: String) + private suspend fun assertUntil(maxWait: Duration, assertion: suspend () -> Unit) { val startTime = System.currentTimeMillis() lateinit var lastAssertionError: AssertionError