Skip to content

Commit 790e571

Browse files
committed
map Swift errors to HTTP return codes (#2)
1 parent f3b145d commit 790e571

File tree

1 file changed

+41
-14
lines changed

1 file changed

+41
-14
lines changed

Sources/OpenAPILambdaHandler.swift

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
//
1414
//===----------------------------------------------------------------------===//
1515
import AWSLambdaRuntime
16-
import OpenAPIRuntime
17-
1816
import AWSLambdaEvents
17+
import OpenAPIRuntime
18+
import HTTPTypes
1919

2020
/// Specialization of LambdaHandler which runs an OpenAPILambda
2121
public struct OpenAPILambdaHandler<L: OpenAPILambda>: LambdaHandler {
@@ -47,21 +47,48 @@ public struct OpenAPILambdaHandler<L: OpenAPILambda>: LambdaHandler {
4747
/// - Returns: A Lambda result ot type `Output`.
4848
public func handle(_ request: Event, context: LambdaContext) async throws -> Output {
4949

50-
// convert Lambda event source to OpenAPILambdaRequest
51-
let request = try lambda.request(context: context, from: request)
50+
// by default return HTTP 500
51+
var lambdaResponse: OpenAPILambdaResponse = (HTTPResponse(status: .internalServerError), "unknown error")
52+
53+
do {
54+
// convert Lambda event source to OpenAPILambdaRequest
55+
let request = try lambda.request(context: context, from: request)
56+
57+
// route the request to find the handlers and extract the paramaters
58+
let (handler, parameters) = try await router.route(method: request.0.method, path: request.0.path!)
59+
60+
// call the request handler (and extract the HTTPRequest and HTTPBody)
61+
let httpRequest = request.0
62+
let httpBody = HTTPBody(stringLiteral: request.1 ?? "")
63+
let response = try await handler(httpRequest, httpBody, ServerRequestMetadata(pathParameters: parameters))
64+
65+
// transform the response to an OpenAPILambdaResponse
66+
let maxPayloadSize = 10 * 1024 * 1024 // APIGateway payload is 10M max
67+
let body: String? = try? await String(collecting: response.1 ?? "", upTo: maxPayloadSize)
68+
lambdaResponse = (response.0, body)
69+
70+
} catch OpenAPILambdaRouterError.noHandlerForPath(let path) {
71+
72+
// There is no hadler registered for this path. This is a programming error.
73+
lambdaResponse = (HTTPResponse(status: .internalServerError), "There is no OpenAPI handler registered for the path \(path)")
74+
75+
} catch OpenAPILambdaRouterError.noRouteForMethod(let method) {
76+
77+
// There is no hadler registered for this path. This is a programming error.
78+
lambdaResponse = (HTTPResponse(status: .notFound), "There is no route registered for the method \(method)")
5279

53-
// route the request to find the handlers and extract the paramaters
54-
let (handler, parameters) = try await router.route(method: request.0.method, path: request.0.path!)
80+
} catch OpenAPILambdaRouterError.noRouteForPath(let path) {
81+
82+
// There is no hadler registered for this path. This is a programming error.
83+
lambdaResponse = (HTTPResponse(status: .notFound), "There is no route registered for the path \(path)")
5584

56-
// call the request handler (and extract the HTTPRequest and HTTPBody)
57-
let httpRequest = request.0
58-
let httpBody = HTTPBody(stringLiteral: request.1 ?? "")
59-
let response = try await handler(httpRequest, httpBody, ServerRequestMetadata(pathParameters: parameters))
85+
} catch OpenAPILambdaHttpError.invalidMethod(let method) {
86+
87+
// the APIGateway HTTP verb is rejected by HTTTypes HTTPRequest.Method => HTTP 500
88+
// this should never happen
89+
lambdaResponse = (HTTPResponse(status: .internalServerError), "Type mismatch between APIGatewayV2 and HTTPRequest.Method. \(method) verb is rejected by HTTPRequest.Method 🤷‍♂️")
6090

61-
// transform the response to an OpenAPILambdaResponse
62-
let maxPayloadSize = 10 * 1024 * 1024 // APIGateway payload is 10M max
63-
let body: String? = try? await String(collecting: response.1 ?? "", upTo: maxPayloadSize)
64-
let lambdaResponse: OpenAPILambdaResponse = (response.0, body)
91+
}
6592

6693
// transform the OpenAPILambdaResponse to the Lambda Output
6794
return lambda.output(from: lambdaResponse)

0 commit comments

Comments
 (0)