Skip to content

Commit 7a4188b

Browse files
author
Gayathri Sairamkrishnan
committed
Convert undocumented errors to 500
1 parent f0934de commit 7a4188b

File tree

2 files changed

+29
-34
lines changed

2 files changed

+29
-34
lines changed

Sources/OpenAPIRuntime/Interface/ErrorHandlingMiddleware.swift

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the SwiftOpenAPIGenerator open source project
44
//
5-
// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors
5+
// Copyright (c) 2024 Apple Inc. and the SwiftOpenAPIGenerator project authors
66
// Licensed under Apache License v2.0
77
//
88
// See LICENSE.txt for license information
@@ -14,16 +14,14 @@
1414

1515
import HTTPTypes
1616

17-
/// Error Handling middleware that converts an error to a HTTP response
17+
/// An opt-in error Handling middleware that converts an error to a HTTP response.
1818
///
19-
/// This is an opt-in middleware that adopters may choose to include to convert application errors
20-
/// to a HTTP Response
21-
///
22-
/// Inclusion of this ErrorHandling Middleware should be accompanied by confirming errors to
23-
/// HTTPResponseConvertible protocol. Only errors confirming to HTTPResponseConvertible are converted to a HTTP response. Other errors are re-thrown from this middleware.
19+
/// Inclusion of ``ErrorHandlingMiddleware`` should be accompanied by confirming errors to ``HTTPResponseConvertible`` protocol.
20+
/// Undocumented errors, i.e, errors not confriming to ``HTTPResponseConvertible`` are converted to a response with 500 status code.
2421
///
2522
/// Example usage
26-
/// 1. Create an error type that conforms to HTTPResponseConvertible protocol
23+
/// 1. Create an error type that conforms to HTTPResponseConvertible protocol:
24+
///
2725
/// ```swift
2826
/// extension MyAppError: HTTPResponseConvertible {
2927
/// var httpStatus: HTTPResponse.Status {
@@ -37,13 +35,15 @@ import HTTPTypes
3735
/// }
3836
/// ```
3937
///
40-
/// 2. Opt in to the error middleware while registering the handler
38+
/// 2. Opt in to the ``ErrorHandlingMiddleware`` while registering the handler:
4139
///
4240
/// ```swift
4341
/// let handler = try await RequestHandler()
4442
/// try handler.registerHandlers(on: transport, middlewares: [ErrorHandlingMiddleware()])
45-
///
46-
43+
/// ```
44+
/// - Note: The placement of ``ErrorHandlingMiddleware`` in the middleware chain is important.
45+
/// It should be determined based on the specific needs of each application.
46+
/// Consider the order of execution and dependencies between middlewares.
4747
public struct ErrorHandlingMiddleware: ServerMiddleware {
4848
public func intercept(_ request: HTTPTypes.HTTPRequest,
4949
body: OpenAPIRuntime.HTTPBody?,
@@ -57,29 +57,28 @@ public struct ErrorHandlingMiddleware: ServerMiddleware {
5757
return (HTTPResponse(status: appError.httpStatus, headerFields: appError.httpHeaderFields),
5858
appError.httpBody)
5959
} else {
60-
throw error
60+
return (HTTPResponse(status: .internalServerError), nil)
6161
}
6262
}
6363
}
6464
}
6565

66-
/// Protocol used by ErrorHandling middleware to map an error to a HTTPResponse
67-
///
68-
/// Adopters who wish to convert their application error to a HTTPResponse
69-
/// should confirm their error(s) to this protocol
70-
66+
/// Protocol used by ErrorHandling middleware to map an error to a HTTPResponse.
67+
/// Adopters who wish to convert their application error to a HTTPResponse should confirm their error(s) to this protocol.
7168
public protocol HTTPResponseConvertible {
72-
/// HTTP status to return in the response
69+
70+
/// HTTP status to return in the response.
7371
var httpStatus: HTTPResponse.Status { get }
7472

75-
/// (Optional) Headers to return in the response
73+
/// Headers to return in the response.
74+
/// This is optional as default values are provided in the extension.
7675
var httpHeaderFields: HTTPTypes.HTTPFields { get }
7776

7877
/// (Optional) The body of the response to return
7978
var httpBody: OpenAPIRuntime.HTTPBody? { get }
8079
}
8180

82-
/// Extension to HTTPResponseConvertible to provide default values for certian fields
81+
/// Extension to HTTPResponseConvertible to provide default values for certian fields.
8382
public extension HTTPResponseConvertible {
8483
var httpHeaderFields: HTTPTypes.HTTPFields { [:] }
8584
var httpBody: OpenAPIRuntime.HTTPBody? { nil }

Tests/OpenAPIRuntimeTests/Interface/Test_ErrorHandlingMiddleware.swift

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the SwiftOpenAPIGenerator open source project
44
//
5-
// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors
5+
// Copyright (c) 2024 Apple Inc. and the SwiftOpenAPIGenerator project authors
66
// Licensed under Apache License v2.0
77
//
88
// See LICENSE.txt for license information
@@ -46,24 +46,20 @@ final class Test_ErrorHandlingMiddlewareTests: XCTestCase {
4646
let (response, responseBody) = try await Test_ErrorHandlingMiddlewareTests.errorHandlingMiddleware.intercept(Test_ErrorHandlingMiddlewareTests.mockRequest,
4747
body: Test_ErrorHandlingMiddlewareTests.mockBody,
4848
metadata: .init(), operationID: "testop",
49-
next: getNextMiddleware(failurePhase: .partialConvertibleError))
49+
next: getNextMiddleware(failurePhase: .partialConvertibleError))
5050
XCTAssertEqual(response.status, .badRequest)
5151
XCTAssertEqual(response.headerFields, [:])
5252
XCTAssertEqual(responseBody, nil)
5353
}
5454

55-
func testError_notConfirmingToProtocol_throws() async throws {
56-
57-
do {
58-
_ = try await Test_ErrorHandlingMiddlewareTests.errorHandlingMiddleware.intercept(Test_ErrorHandlingMiddlewareTests.mockRequest,
59-
body: Test_ErrorHandlingMiddlewareTests.mockBody,
60-
metadata: .init(), operationID: "testop",
61-
next: getNextMiddleware(failurePhase: .nonConvertibleError))
62-
XCTFail("Expected error to be thrown")
63-
} catch {
64-
let error = error as? ServerError
65-
XCTAssertTrue(error?.underlyingError is NonConvertibleError)
66-
}
55+
func testError_notConfirmingToProtocol_returns500() async throws {
56+
let (response, responseBody) = try await Test_ErrorHandlingMiddlewareTests.errorHandlingMiddleware.intercept(Test_ErrorHandlingMiddlewareTests.mockRequest,
57+
body: Test_ErrorHandlingMiddlewareTests.mockBody,
58+
metadata: .init(), operationID: "testop",
59+
next: getNextMiddleware(failurePhase: .nonConvertibleError))
60+
XCTAssertEqual(response.status, .internalServerError)
61+
XCTAssertEqual(response.headerFields, [:])
62+
XCTAssertEqual(responseBody, nil)
6763
}
6864

6965
private func getNextMiddleware(failurePhase: MockErrorMiddleware_Next.FailurePhase) -> @Sendable (HTTPTypes.HTTPRequest,

0 commit comments

Comments
 (0)