Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS API Gateway Error Handling with Generated SDK (Swift)

I'm fairly new to AWS and using API Gateway -> Lambda -> RDS. Also, I'm using the generated SDK for Swift in my iOS mobile application that is consuming the API.

The straight forward paths work fine when returning success (200). However, I'm trying to add in more error handling for edge cases. If an API request doesn't find the resource it's expected, I'm trying to return a 404 error. I've added this to the API Integration Response and Method Response appropriately. I can test this and get my error model returned as expected along with the correct HTTP Status code of 404.

However, I'm struggling with how to handle this on the mobile application side. How would this be handled by the generated SDK? It just throws an error in the API call and I expected a way to retrieve my "Error" model object that I've defined.

Here is normal path

Here is failed path with 404

Generated SDK (Swift) method:

public func userUseridentityGet(useridentity: String) -> AWSTask<RSAPI_UserModel> {
let headerParameters = [
    "Content-Type": "application/json",
    "Accept": "application/json",           
]

let queryParameters:[String:Any] = [:]

var pathParameters:[String:Any] = [:]
pathParameters["useridentity"] = useridentity

return self.invokeHTTPRequest("GET", urlString: "/user/{useridentity}", pathParameters: pathParameters, queryParameters: queryParameters, headerParameters: headerParameters, body: nil, responseClass: RSAPI_UserModel.self) as! AWSTask<RSAPI_UserModel>
}

At runtime, I get the following logged out when I print the error out:

Error occurred: Error Domain=com.amazonaws.AWSAPIGatewayErrorDomain Code=1 "(null)" UserInfo={HTTPBody={ code = 404; message = "No Result Found."; "request-id" = "132b8eaa-7b24-11e7-b1fd-d342f0413b7d"; type = NotFound; }, HTTPHeaderFields={type = immutable dict, count = 8, entries => 0 : x-cache = {contents = "Error from cloudfront"} 1 : Content-Type = {contents = "application/json"} 3 : x-amzn-requestid = {contents = "131a5075-7b24-11e7-87bd-9fcb4cb4e04e"} 4 : Via = {contents = "1.1 bd4761ff0774f9ee778140b91a0431c9.cloudfront.net (CloudFront)"} 6 : Date = {contents = "Mon, 07 Aug 2017 03:54:13 GMT"} 10 : Content-Length = 134 11 : x-amzn-trace-id = {contents = "sampled=0;root=1-5987e464-d3d8f7801b7ae5aa6a52fc1b"} 12 : x-amz-cf-id = {contents = "QKpl64W1qDaeo0zlsx2iOwTW0oO_jyPRmMT7ByPKLnen04qiPEeD6w=="} } }

The question is how do I get that de-serialized into my "Error" object model that I've defined? How do I appropriately detect this error condition so I can write logic in my mobile application to handle it?

like image 827
Shawn Avatar asked Mar 07 '26 09:03

Shawn


1 Answers

For a workaround, I've just handled this by manually extracting out the data. If anyone has a better way of dealing with this. I'd definitely be interested.

if let error = task?.error as NSError? {
    print("Error occurred: \(error)")
    if error.code == 1 {
        let httpBody : NSDictionary = (error.userInfo["HTTPBody"] as? NSDictionary)!
        print("Code \(httpBody["code"] ?? "none") - Type \(httpBody["type"] ?? "none") - Message \(httpBody["message"] ?? "none") - RequestID \(httpBody["request-id"] ?? "none")")
    }
    return nil
}
like image 200
Shawn Avatar answered Mar 08 '26 23:03

Shawn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!