@@ -38,31 +38,38 @@ import struct Foundation.URL
38
38
/// The middlewares to be invoked before the transport.
39
39
public var middlewares : [ any ClientMiddleware ]
40
40
41
+ /// An error mapping closure to allow customizing the error thrown by the client.
42
+ public var errorMapper : ( @Sendable ( ClientError ) -> any Error ) ?
43
+
41
44
/// Internal initializer that takes an initialized `Converter`.
42
45
internal init (
43
46
serverURL: URL ,
44
47
converter: Converter ,
45
48
transport: any ClientTransport ,
46
- middlewares: [ any ClientMiddleware ]
49
+ middlewares: [ any ClientMiddleware ] ,
50
+ errorMapper: ( @Sendable ( ClientError ) -> any Error ) ?
47
51
) {
48
52
self . serverURL = serverURL
49
53
self . converter = converter
50
54
self . transport = transport
51
55
self . middlewares = middlewares
56
+ self . errorMapper = errorMapper
52
57
}
53
58
54
59
/// Creates a new client.
55
60
public init (
56
61
serverURL: URL = . defaultOpenAPIServerURL,
57
62
configuration: Configuration = . init( ) ,
58
63
transport: any ClientTransport ,
59
- middlewares: [ any ClientMiddleware ] = [ ]
64
+ middlewares: [ any ClientMiddleware ] = [ ] ,
65
+ errorMapper: ( @Sendable ( ClientError ) -> any Error ) ? = nil
60
66
) {
61
67
self . init (
62
68
serverURL: serverURL,
63
69
converter: Converter ( configuration: configuration) ,
64
70
transport: transport,
65
- middlewares: middlewares
71
+ middlewares: middlewares,
72
+ errorMapper: errorMapper
66
73
)
67
74
}
68
75
@@ -135,57 +142,65 @@ import struct Foundation.URL
135
142
underlyingError: underlyingError
136
143
)
137
144
}
138
- let ( request, requestBody) : ( HTTPRequest , HTTPBody ? ) = try await wrappingErrors {
139
- try serializer ( input)
140
- } mapError: { error in
141
- makeError ( error: error)
142
- }
143
- var next : @Sendable ( HTTPRequest, HTTPBody? , URL) async throws -> ( HTTPResponse , HTTPBody ? ) = {
144
- ( _request, _body, _url) in
145
- try await wrappingErrors {
146
- try await transport. send ( _request, body: _body, baseURL: _url, operationID: operationID)
145
+ do {
146
+ let ( request, requestBody) : ( HTTPRequest , HTTPBody ? ) = try await wrappingErrors {
147
+ try serializer ( input)
147
148
} mapError: { error in
148
- makeError (
149
- request: request,
150
- requestBody: requestBody,
151
- baseURL: baseURL,
152
- error: RuntimeError . transportFailed ( error)
153
- )
149
+ makeError ( error: error)
154
150
}
155
- }
156
- for middleware in middlewares. reversed ( ) {
157
- let tmp = next
158
- next = { ( _request, _body, _url) in
151
+ var next : @Sendable ( HTTPRequest, HTTPBody? , URL) async throws -> ( HTTPResponse , HTTPBody ? ) = {
152
+ ( _request, _body, _url) in
159
153
try await wrappingErrors {
160
- try await middleware. intercept (
161
- _request,
162
- body: _body,
163
- baseURL: _url,
164
- operationID: operationID,
165
- next: tmp
166
- )
154
+ try await transport. send ( _request, body: _body, baseURL: _url, operationID: operationID)
167
155
} mapError: { error in
168
156
makeError (
169
157
request: request,
170
158
requestBody: requestBody,
171
159
baseURL: baseURL,
172
- error: RuntimeError . middlewareFailed ( middlewareType : type ( of : middleware ) , error)
160
+ error: RuntimeError . transportFailed ( error)
173
161
)
174
162
}
175
163
}
176
- }
177
- let ( response, responseBody) : ( HTTPResponse , HTTPBody ? ) = try await next ( request, requestBody, baseURL)
178
- return try await wrappingErrors {
179
- try await deserializer ( response, responseBody)
180
- } mapError: { error in
181
- makeError (
182
- request: request,
183
- requestBody: requestBody,
184
- baseURL: baseURL,
185
- response: response,
186
- responseBody: responseBody,
187
- error: error
188
- )
164
+ for middleware in middlewares. reversed ( ) {
165
+ let tmp = next
166
+ next = { ( _request, _body, _url) in
167
+ try await wrappingErrors {
168
+ try await middleware. intercept (
169
+ _request,
170
+ body: _body,
171
+ baseURL: _url,
172
+ operationID: operationID,
173
+ next: tmp
174
+ )
175
+ } mapError: { error in
176
+ makeError (
177
+ request: request,
178
+ requestBody: requestBody,
179
+ baseURL: baseURL,
180
+ error: RuntimeError . middlewareFailed ( middlewareType: type ( of: middleware) , error)
181
+ )
182
+ }
183
+ }
184
+ }
185
+ let ( response, responseBody) : ( HTTPResponse , HTTPBody ? ) = try await next ( request, requestBody, baseURL)
186
+ return try await wrappingErrors {
187
+ try await deserializer ( response, responseBody)
188
+ } mapError: { error in
189
+ makeError (
190
+ request: request,
191
+ requestBody: requestBody,
192
+ baseURL: baseURL,
193
+ response: response,
194
+ responseBody: responseBody,
195
+ error: error
196
+ )
197
+ }
198
+ } catch {
199
+ if let errorMapper, let clientError = error as? ClientError {
200
+ throw errorMapper ( clientError)
201
+ } else {
202
+ throw error
203
+ }
189
204
}
190
205
}
191
206
}
0 commit comments