Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0cbccaf

Browse files
Add more test. Runtime error handling fix
1 parent 225ddd8 commit 0cbccaf

File tree

2 files changed

+98
-24
lines changed

2 files changed

+98
-24
lines changed

‎lambda-runtime/src/commonMain/kotlin/io/github/trueangle/knative/lambda/runtime/LambdaRuntime.kt

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import kotlinx.serialization.json.Json
3434
object LambdaRuntime {
3535
@OptIn(ExperimentalSerializationApi::class)
3636
internal val json = Json { explicitNulls = false }
37+
3738
@PublishedApi
3839
internal val curlHttpClient = createHttpClient(Curl.create())
3940

@@ -85,35 +86,37 @@ internal class Runner(
8586
try {
8687
log.info("Runtime is ready for a new event")
8788

88-
val (event, context) = client.retrieveNextEvent<I>(inputTypeInfo)
89+
try {
90+
val (event, context) = client.retrieveNextEvent<I>(inputTypeInfo)
8991

90-
with(log) {
91-
setContext(context)
92+
with(log) {
93+
setContext(context)
9294

93-
debug(event)
94-
debug(context)
95-
info("$handlerName invocation started")
96-
}
95+
debug(event)
96+
debug(context)
97+
info("$handlerName invocation started")
98+
}
9799

98-
if (handler is LambdaStreamHandler<I, *>) {
99-
val response = streamingResponse { handler.handleRequest(event, it, context) }
100+
if (handler is LambdaStreamHandler<I, *>) {
101+
val response = streamingResponse { handler.handleRequest(event, it, context) }
100102

101-
log.info("$handlerName started response streaming")
103+
log.info("$handlerName started response streaming")
102104

103-
client.streamResponse(context, response)
104-
} else {
105-
handler as LambdaBufferedHandler<I, O>
106-
val response = bufferedResponse(context) { handler.handleRequest(event, context) }
105+
client.streamResponse(context, response)
106+
} else {
107+
handler as LambdaBufferedHandler<I, O>
108+
val response = bufferedResponse(context) { handler.handleRequest(event, context) }
107109

108-
log.info("$handlerName invocation completed")
109-
log.debug(response)
110+
log.info("$handlerName invocation completed")
111+
log.debug(response)
110112

111-
client.sendResponse(context, response, outputTypeInfo)
112-
}
113-
} catch (e: LambdaRuntimeException) {
114-
log.error(e)
113+
client.sendResponse(context, response, outputTypeInfo)
114+
}
115+
} catch (e: LambdaRuntimeException) {
116+
log.error(e)
115117

116-
client.reportError(e)
118+
client.reportError(e)
119+
}
117120
} catch (e: LambdaEnvironmentException) {
118121
when (e) {
119122
is NonRecoverableStateException -> {

‎lambda-runtime/src/nativeTest/kotlin/io/github/trueangle/knative/lambda/runtime/LambdaRuntimeTest.kt

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import dev.mokkery.spy
99
import dev.mokkery.verify
1010
import dev.mokkery.verify.VerifyMode.Companion.exactly
1111
import dev.mokkery.verify.VerifyMode.Companion.not
12+
import dev.mokkery.verify.VerifyMode.Companion.order
1213
import dev.mokkery.verifySuspend
14+
import io.github.trueangle.knative.lambda.runtime.LambdaEnvironmentException.*
1315
import io.github.trueangle.knative.lambda.runtime.LambdaRuntimeException.Invocation.EventBodyParseException
1416
import io.github.trueangle.knative.lambda.runtime.LambdaRuntimeException.Invocation.HandlerException
1517
import io.github.trueangle.knative.lambda.runtime.ReservedRuntimeEnvironmentVariables.AWS_LAMBDA_FUNCTION_NAME
@@ -191,7 +193,7 @@ class LambdaRuntimeTest {
191193
}
192194

193195
@Test
194-
fun `GIVEN api error WHEN retrieveNextEvent THEN terminate`() = runTest {
196+
fun `GIVEN env api error WHEN retrieveNextEvent THEN terminate`() = runTest {
195197
val lambdaRunner = createRunner(MockEngine { request ->
196198
val path = request.url.encodedPath
197199
when {
@@ -213,6 +215,75 @@ class LambdaRuntimeTest {
213215
verify { log.log(FATAL, any<Any>(), any()) }
214216
}
215217

218+
@Test
219+
fun `GIVEN bad request from env api WHEN sendResponse THEN skip event`() = runTest {
220+
val lambdaRunner = createRunner(MockEngine { request ->
221+
val path = request.url.encodedPath
222+
when {
223+
path.contains("invocation/next") -> respondNextEventSuccess("")
224+
path.contains("${context.awsRequestId}/response") -> respondError(HttpStatusCode.BadGateway)
225+
else -> respondBadRequest()
226+
}
227+
})
228+
val client = lambdaRunner.client
229+
val handler = object : LambdaBufferedHandler<String, String> {
230+
override suspend fun handleRequest(input: String, context: Context) = throw RuntimeException()
231+
}
232+
233+
lambdaRunner.run(singleEventMode = true) { handler }
234+
235+
verifySuspend { client.reportError(any<HandlerException>()) }
236+
verify(order) { log.log(ERROR, any<HandlerException>(), any()) }
237+
verify(order) { log.log(ERROR, any<BadRequestException>(), any()) }
238+
verify(not) { log.log(FATAL, any<Any>(), any()) }
239+
verify(not) { lambdaRunner.env.terminate() }
240+
}
241+
242+
@Test
243+
fun `GIVEN unknown http error from env api WHEN reportError THEN skip event`() = runTest {
244+
val lambdaRunner = createRunner(MockEngine { request ->
245+
val path = request.url.encodedPath
246+
when {
247+
path.contains("invocation/next") -> respondNextEventSuccess("")
248+
else -> respondBadRequest()
249+
}
250+
})
251+
val client = lambdaRunner.client
252+
val handler = object : LambdaBufferedHandler<String, String> {
253+
override suspend fun handleRequest(input: String, context: Context) = throw RuntimeException()
254+
}
255+
256+
lambdaRunner.run(singleEventMode = true) { handler }
257+
258+
verifySuspend { client.reportError(any<HandlerException>()) }
259+
verify(order) { log.log(ERROR, any<HandlerException>(), any()) }
260+
verify(order) { log.log(ERROR, any<BadRequestException>(), any()) }
261+
verify(not) { log.log(FATAL, any<Any>(), any()) }
262+
verify(not) { lambdaRunner.env.terminate() }
263+
}
264+
265+
@Test
266+
fun `GIVEN internal server error from env api WHEN reportError THEN terminate`() = runTest {
267+
val lambdaRunner = createRunner(MockEngine { request ->
268+
val path = request.url.encodedPath
269+
when {
270+
path.contains("invocation/next") -> respondNextEventSuccess("")
271+
path.contains("${context.awsRequestId}/error") -> respondError(HttpStatusCode.InternalServerError)
272+
else -> respondBadRequest()
273+
}
274+
})
275+
val client = lambdaRunner.client
276+
val handler = object : LambdaBufferedHandler<String, String> {
277+
override suspend fun handleRequest(input: String, context: Context) = throw RuntimeException()
278+
}
279+
280+
assertFailsWith<TerminateException> { lambdaRunner.run(singleEventMode = true) { handler } }
281+
verifySuspend { client.reportError(any<HandlerException>()) }
282+
verify { log.log(ERROR, any<HandlerException>(), any()) }
283+
verify { log.log(FATAL, any<NonRecoverableStateException>(), any()) }
284+
verify { lambdaRunner.env.terminate() }
285+
}
286+
216287
@Test
217288
fun `GIVEN EventBodyParseException WHEN retrieveNextEvent THEN report error AND skip event`() = runTest {
218289
val event = NonSerialObject("")
@@ -238,7 +309,7 @@ class LambdaRuntimeTest {
238309
}
239310

240311
@Test
241-
fun `GIVEN Handler exception WHEN handleRequest THEN report error AND skip event`() = runTest {
312+
fun `GIVEN Handler exception WHEN invoke handler THEN report error AND skip event`() = runTest {
242313
val lambdaRunner = createRunner(MockEngine { request ->
243314
val path = request.url.encodedPath
244315
when {
@@ -261,7 +332,7 @@ class LambdaRuntimeTest {
261332
}
262333

263334
@Test
264-
fun `GIVEN Handler exception WHEN streamingResponse THEN consume error`() = runTest {
335+
fun `GIVEN Handler exception WHEN invoke streaming handler THEN consume error`() = runTest {
265336
val lambdaRunner = createRunner(MockEngine { request ->
266337
val path = request.url.encodedPath
267338
when {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /