Skip to content

Commit 8c2267c

Browse files
authored
Merge pull request #3624 from ButterflyNetwork/swift-better-errors
[Swift] Include HTTP status code and body data in response errors
2 parents 25a14f5 + e89f914 commit 8c2267c

22 files changed

Lines changed: 389 additions & 379 deletions

File tree

modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
6363
}
6464
self.processRequest(uploadRequest, managerId, completion)
6565
case .Failure(let encodingError):
66-
completion(response: nil, error: encodingError)
66+
completion(response: nil, error: ErrorResponse.Error(415, nil, encodingError))
6767
}
6868
}
6969
)
@@ -89,14 +89,54 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
8989
let validatedRequest = request.validate()
9090

9191
switch T.self {
92+
case is String.Type:
93+
validatedRequest.responseString(completionHandler: { (stringResponse) in
94+
cleanupRequest()
95+
96+
if stringResponse.result.isFailure {
97+
completion(
98+
response: nil,
99+
error: ErrorResponse.Error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error!)
100+
)
101+
return
102+
}
103+
104+
completion(
105+
response: Response(
106+
response: stringResponse.response!,
107+
body: (stringResponse.result.value ?? "") as! T
108+
),
109+
error: nil
110+
)
111+
})
112+
case is Void.Type:
113+
validatedRequest.responseData(completionHandler: { (voidResponse) in
114+
cleanupRequest()
115+
116+
if voidResponse.result.isFailure {
117+
completion(
118+
response: nil,
119+
error: ErrorResponse.Error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!)
120+
)
121+
return
122+
}
123+
124+
completion(
125+
response: Response(
126+
response: voidResponse.response!,
127+
body: nil
128+
),
129+
error: nil
130+
)
131+
})
92132
case is NSData.Type:
93133
validatedRequest.responseData(completionHandler: { (dataResponse) in
94134
cleanupRequest()
95135
96136
if (dataResponse.result.isFailure) {
97137
completion(
98138
response: nil,
99-
error: dataResponse.result.error
139+
error: ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
100140
)
101141
return
102142
}
@@ -114,7 +154,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
114154
cleanupRequest()
115155
116156
if response.result.isFailure {
117-
completion(response: nil, error: response.result.error)
157+
completion(response: nil, error: ErrorResponse.Error(response.response?.statusCode ?? 500, response.data, response.result.error!))
118158
return
119159
}
120160

@@ -133,7 +173,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
133173
return
134174
}
135175
136-
completion(response: nil, error: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
176+
completion(response: nil, error: ErrorResponse.Error(500, nil, NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])))
137177
}
138178
}
139179
}

modules/swagger-codegen/src/main/resources/swift/Models.mustache

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,22 @@ protocol JSONEncodable {
1010
func encodeToJSON() -> AnyObject
1111
}
1212

13+
public enum ErrorResponse : ErrorType {
14+
case Error(Int, NSData?, ErrorType)
15+
}
16+
1317
public class Response<T> {
1418
public let statusCode: Int
1519
public let header: [String: String]
16-
public let body: T
20+
public let body: T?
1721
18-
public init(statusCode: Int, header: [String: String], body: T) {
22+
public init(statusCode: Int, header: [String: String], body: T?) {
1923
self.statusCode = statusCode
2024
self.header = header
2125
self.body = body
2226
}
2327

24-
public convenience init(response: NSHTTPURLResponse, body: T) {
28+
public convenience init(response: NSHTTPURLResponse, body: T?) {
2529
let rawHeader = response.allHeaderFields
2630
var header = [String:String]()
2731
for (key, value) in rawHeader {

samples/client/petstore/swift/default/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,13 @@ public class PetAPI: APIBase {
108108
- OAuth:
109109
- type: oauth2
110110
- name: petstore_auth
111-
- examples: [{example={
111+
- examples: [{contentType=application/json, example={
112112
"name" : "Puma",
113113
"type" : "Dog",
114114
"color" : "Black",
115115
"gender" : "Female",
116116
"breed" : "Mixed"
117-
}, contentType=application/json}]
117+
}}]
118118

119119
- parameter status: (query) Status values that need to be considered for filter (optional, default to available)
120120

@@ -157,20 +157,20 @@ public class PetAPI: APIBase {
157157
- OAuth:
158158
- type: oauth2
159159
- name: petstore_auth
160-
- examples: [{example=[ {
161-
"tags" : [ {
162-
"id" : 123456789,
163-
"name" : "aeiou"
164-
} ],
160+
- examples: [{contentType=application/json, example=[ {
161+
"photoUrls" : [ "aeiou" ],
162+
"name" : "doggie",
165163
"id" : 123456789,
166164
"category" : {
167-
"id" : 123456789,
168-
"name" : "aeiou"
165+
"name" : "aeiou",
166+
"id" : 123456789
169167
},
170-
"status" : "aeiou",
171-
"name" : "doggie",
172-
"photoUrls" : [ "aeiou" ]
173-
} ], contentType=application/json}, {example=<Pet>
168+
"tags" : [ {
169+
"name" : "aeiou",
170+
"id" : 123456789
171+
} ],
172+
"status" : "aeiou"
173+
} ]}, {contentType=application/xml, example=<Pet>
174174
<id>123456</id>
175175
<name>doggie</name>
176176
<photoUrls>
@@ -179,21 +179,21 @@ public class PetAPI: APIBase {
179179
<tags>
180180
</tags>
181181
<status>string</status>
182-
</Pet>, contentType=application/xml}]
183-
- examples: [{example=[ {
184-
"tags" : [ {
185-
"id" : 123456789,
186-
"name" : "aeiou"
187-
} ],
182+
</Pet>}]
183+
- examples: [{contentType=application/json, example=[ {
184+
"photoUrls" : [ "aeiou" ],
185+
"name" : "doggie",
188186
"id" : 123456789,
189187
"category" : {
190-
"id" : 123456789,
191-
"name" : "aeiou"
188+
"name" : "aeiou",
189+
"id" : 123456789
192190
},
193-
"status" : "aeiou",
194-
"name" : "doggie",
195-
"photoUrls" : [ "aeiou" ]
196-
} ], contentType=application/json}, {example=<Pet>
191+
"tags" : [ {
192+
"name" : "aeiou",
193+
"id" : 123456789
194+
} ],
195+
"status" : "aeiou"
196+
} ]}, {contentType=application/xml, example=<Pet>
197197
<id>123456</id>
198198
<name>doggie</name>
199199
<photoUrls>
@@ -202,7 +202,7 @@ public class PetAPI: APIBase {
202202
<tags>
203203
</tags>
204204
<status>string</status>
205-
</Pet>, contentType=application/xml}]
205+
</Pet>}]
206206

207207
- parameter tags: (query) Tags to filter by (optional)
208208

@@ -242,26 +242,26 @@ public class PetAPI: APIBase {
242242
Find pet by ID
243243
- GET /pet/{petId}
244244
- Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions
245-
- API Key:
246-
- type: apiKey api_key
247-
- name: api_key
248245
- OAuth:
249246
- type: oauth2
250247
- name: petstore_auth
251-
- examples: [{example={
252-
"tags" : [ {
253-
"id" : 123456789,
254-
"name" : "aeiou"
255-
} ],
248+
- API Key:
249+
- type: apiKey api_key
250+
- name: api_key
251+
- examples: [{contentType=application/json, example={
252+
"photoUrls" : [ "aeiou" ],
253+
"name" : "doggie",
256254
"id" : 123456789,
257255
"category" : {
258-
"id" : 123456789,
259-
"name" : "aeiou"
256+
"name" : "aeiou",
257+
"id" : 123456789
260258
},
261-
"status" : "aeiou",
262-
"name" : "doggie",
263-
"photoUrls" : [ "aeiou" ]
264-
}, contentType=application/json}, {example=<Pet>
259+
"tags" : [ {
260+
"name" : "aeiou",
261+
"id" : 123456789
262+
} ],
263+
"status" : "aeiou"
264+
}}, {contentType=application/xml, example=<Pet>
265265
<id>123456</id>
266266
<name>doggie</name>
267267
<photoUrls>
@@ -270,21 +270,21 @@ public class PetAPI: APIBase {
270270
<tags>
271271
</tags>
272272
<status>string</status>
273-
</Pet>, contentType=application/xml}]
274-
- examples: [{example={
275-
"tags" : [ {
276-
"id" : 123456789,
277-
"name" : "aeiou"
278-
} ],
273+
</Pet>}]
274+
- examples: [{contentType=application/json, example={
275+
"photoUrls" : [ "aeiou" ],
276+
"name" : "doggie",
279277
"id" : 123456789,
280278
"category" : {
281-
"id" : 123456789,
282-
"name" : "aeiou"
279+
"name" : "aeiou",
280+
"id" : 123456789
283281
},
284-
"status" : "aeiou",
285-
"name" : "doggie",
286-
"photoUrls" : [ "aeiou" ]
287-
}, contentType=application/json}, {example=<Pet>
282+
"tags" : [ {
283+
"name" : "aeiou",
284+
"id" : 123456789
285+
} ],
286+
"status" : "aeiou"
287+
}}, {contentType=application/xml, example=<Pet>
288288
<id>123456</id>
289289
<name>doggie</name>
290290
<photoUrls>
@@ -293,7 +293,7 @@ public class PetAPI: APIBase {
293293
<tags>
294294
</tags>
295295
<status>string</status>
296-
</Pet>, contentType=application/xml}]
296+
</Pet>}]
297297

298298
- parameter petId: (path) ID of pet that needs to be fetched
299299

0 commit comments

Comments
 (0)