Skip to content

Commit 628c569

Browse files
ruibritoptmduesterhoeft
authored andcommitted
imprv: add InvalidFormatException to 422 mapping error (#13)
* imprv: add InvalidFormatException to 422 mapping errors * imprv: add test * imprv: remove hooker method * imprv: override method implementation (test) * imprv: override method implementation (test) - fix
1 parent 81240dc commit 628c569

File tree

3 files changed

+38
-13
lines changed

3 files changed

+38
-13
lines changed

router-protobuf/src/test/kotlin/io/moia/router/proto/RequestHandlerTest.kt

+8-6
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,13 @@ class RequestHandlerTest {
121121
.setCode(error.code)
122122
.build()
123123

124-
override fun createUnprocessableEntityErrorBody(error: UnprocessableEntityError): Any =
125-
io.moia.router.proto.sample.SampleOuterClass.UnprocessableEntityError.newBuilder()
126-
.setMessage(error.message)
127-
.setCode(error.code)
128-
.setPath(error.path)
129-
.build()
124+
override fun createUnprocessableEntityErrorBody(errors: List<UnprocessableEntityError>): Any =
125+
errors.map { error ->
126+
io.moia.router.proto.sample.SampleOuterClass.UnprocessableEntityError.newBuilder()
127+
.setMessage(error.message)
128+
.setCode(error.code)
129+
.setPath(error.path)
130+
.build()
131+
}
130132
}
131133
}

router/src/main/kotlin/io/moia/router/RequestHandler.kt

+13-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.amazonaws.services.lambda.runtime.Context
44
import com.amazonaws.services.lambda.runtime.RequestHandler
55
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent
66
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent
7+
import com.fasterxml.jackson.databind.exc.InvalidFormatException
78
import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
89
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
910
import com.google.common.net.MediaType
@@ -119,8 +120,7 @@ abstract class RequestHandler : RequestHandler<APIGatewayProxyRequestEvent, APIG
119120
/**
120121
* Customize the format of an unprocessable entity error
121122
*/
122-
open fun createUnprocessableEntityErrorBody(error: UnprocessableEntityError): Any =
123-
error
123+
open fun createUnprocessableEntityErrorBody(errors: List<UnprocessableEntityError>): Any = errors
124124

125125
open fun createApiExceptionErrorResponse(contentType: MediaType, input: APIGatewayProxyRequestEvent, ex: ApiException): APIGatewayProxyResponseEvent =
126126
createErrorBody(ex.toApiError()).let {
@@ -138,12 +138,19 @@ abstract class RequestHandler : RequestHandler<APIGatewayProxyRequestEvent, APIG
138138

139139
open fun createUnexpectedErrorResponse(contentType: MediaType, input: APIGatewayProxyRequestEvent, ex: Exception): APIGatewayProxyResponseEvent =
140140
when (ex) {
141+
is InvalidFormatException ->
142+
createResponse(contentType, input,
143+
ResponseEntity(422, createUnprocessableEntityErrorBody(listOf(
144+
UnprocessableEntityError(
145+
message = "INVALID_FIELD_FORMAT",
146+
code = "FIELD",
147+
path = ex.path.last().fieldName.orEmpty())))))
141148
is MissingKotlinParameterException ->
142149
createResponse(contentType, input,
143-
ResponseEntity(422, createUnprocessableEntityErrorBody(UnprocessableEntityError(
144-
message = "Missing required field",
145-
code = "MISSING_REQUIRED_FIELDS",
146-
path = ex.parameter.name.orEmpty()))))
150+
ResponseEntity(422, createUnprocessableEntityErrorBody(listOf(UnprocessableEntityError(
151+
message = "MISSING_REQUIRED_FIELDS",
152+
code = "FIELD",
153+
path = ex.parameter.name.orEmpty())))))
147154
else -> createResponse(contentType, input,
148155
ResponseEntity(500, createErrorBody(ApiError(ex.message.orEmpty(), "INTERNAL_SERVER_ERROR"))))
149156
}

router/src/test/kotlin/io/moia/router/RequestHandlerTest.kt

+17-1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,22 @@ class RequestHandlerTest {
180180
assert(response.statusCode).isEqualTo(422)
181181
}
182182

183+
@Test
184+
fun `should handle deserialization error, when field has invalid format`() {
185+
186+
val response = testRequestHandler.handleRequest(
187+
POST("/some")
188+
.withHeaders(
189+
mapOf(
190+
"Accept" to "application/json",
191+
"Content-Type" to "application/json"
192+
)
193+
)
194+
.withBody("""{"greeting": "hello","age": "a"}"""), mockk()
195+
)
196+
assert(response.statusCode).isEqualTo(422)
197+
}
198+
183199
@Test
184200
fun `should handle api exception`() {
185201

@@ -390,7 +406,7 @@ class RequestHandlerTest {
390406
class TestRequestHandler : RequestHandler() {
391407

392408
data class TestResponse(val greeting: String)
393-
data class TestRequest(val greeting: String)
409+
data class TestRequest(val greeting: String, val age: Int = 0)
394410

395411
override val router = router {
396412
GET("/some") { _: Request<Unit> ->

0 commit comments

Comments
 (0)