-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHTTPHandler.swift
More file actions
71 lines (65 loc) · 2.12 KB
/
HTTPHandler.swift
File metadata and controls
71 lines (65 loc) · 2.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//
// HTTPHandler.swift
// SimpleHTTP
//
// Created by Edvinas Byla on 14/05/2025.
//
/// A handler in a chain of HTTP handlers.
///
/// Conformers can modify or observe requests/responses and pass them along.
public protocol HTTPHandler: Sendable {
typealias Request = HTTPRequest
typealias Response = HTTPResponse
typealias Handler = HTTPHandler
typealias AnyHandler = any HTTPHandler
/// The next handler in the chain.
var next: Handler? { get set }
/// Processes an HTTP request and returns a response.
///
/// - Parameter request: The request to handle.
/// - Throws: `HTTPError` on failure.
/// - Returns: The HTTP response.
func handle(request: Request) async throws(HTTPError) -> Response
}
extension HTTPHandler {
/// Retrieves the next handler or throws if missing.
///
/// - Throws: `HTTPError.invalidConfiguration` if `next` is `nil`.
public var nextHandler: Handler {
get throws(HTTPError) {
guard let next else {
throw .init(
code: .invalidConfiguration(reason: "Missing handler"),
request: .init(method: .get, path: "")
)
}
return next
}
}
/// Wraps a throwing async block to convert any error into an `HTTPError`.
///
/// - Parameters:
/// - code: The error code to report.
/// - request: The request in flight.
/// - response: Optional response so far.
/// - body: The async block to execute.
/// - Throws: `HTTPError` if `body` throws.
/// - Returns: The block’s return value.
public func withHTTPError<ReturnType: Sendable>(
code: HTTPError.Code,
request: Request,
response: Response? = nil,
body: @Sendable () async throws -> ReturnType
) async throws(HTTPError) -> ReturnType {
do {
return try await body()
} catch {
throw HTTPError(
code: code,
request: request,
response: response,
underlyingError: error
)
}
}
}