Skip to content

Commit 759ff57

Browse files
committed
KTOR-9125 Fix double ResponseSent invocation when exception is thrown after respond (#5215)
1 parent ab108df commit 759ff57

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultEnginePipeline.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import io.ktor.util.cio.*
1717
import io.ktor.util.logging.*
1818
import io.ktor.util.pipeline.*
1919
import io.ktor.utils.io.*
20-
import kotlinx.coroutines.*
2120
import kotlinx.coroutines.CancellationException
21+
import kotlinx.coroutines.TimeoutCancellationException
2222
import kotlinx.io.IOException
2323

2424
/**

ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationEngine.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ public class TestApplicationEngine(
122122

123123
private suspend fun handleTestFailure(call: ApplicationCall, cause: Throwable) {
124124
logError(call, cause)
125+
if (call.response.isSent) return
125126

126127
val throwOnException = environment.config
127128
.propertyOrNull(CONFIG_KEY_THROW_ON_EXCEPTION)

ktor-server/ktor-server-test-suites/common/src/io/ktor/server/testing/suites/HttpServerCommonTestSuite.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,36 @@ abstract class HttpServerCommonTestSuite<TEngine : ApplicationEngine, TConfigura
821821
}
822822
}
823823

824+
@Test
825+
fun testResponseSentCalledOnce() = runTest {
826+
var responseSentCalled = 0
827+
createAndStartServer {
828+
serverConfig {
829+
enableSsl = false
830+
enableHttp2 = false
831+
}
832+
install(
833+
createRouteScopedPlugin("Plugin") {
834+
on(ResponseSent) {
835+
responseSentCalled++
836+
}
837+
}
838+
)
839+
840+
get("/") {
841+
call.respond("ok")
842+
throw ExpectedTestException("exception")
843+
}
844+
}
845+
846+
withUrl("/") {
847+
assertEquals(HttpStatusCode.OK, status)
848+
assertEquals("ok", bodyAsText())
849+
}
850+
delay(500)
851+
assertEquals(1, responseSentCalled)
852+
}
853+
824854
private data class TestData(
825855
val name: String
826856
) : AbstractCoroutineContextElement(TestData) {

0 commit comments

Comments
 (0)