Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get server response message from error

Tags:

alamofire

My server (CakePHP) is responding like so:

$this->response->statusCode('400');
$this->response->type('json');
$this->response->body(json_encode(array('message' => 'Bookmark already exists')));

The Postman output looks like what you would expect:

{"message":"Bookmark already exists"}

The problem is that I cannot find a way to access this message from the failure handler (Alamofire 3.1.3 + SwiftyJSON 2.3.2)

Alamofire.request(.POST...
.validate()
.responseJSON { response in

switch response.result {

case .Success(_):                           
// All good

case .Failure(let error):
// Status code 400                 
print(response.request)  // original URL request
print(response.response) // URL response
print(response.data)     // server data
print(response.result)

I cannot find a way to cast response.data to JSON as a I simply get nil and the result returns just FAILURE.

Is there a way to access this server message from the failure handler ?

like image 326
tompa Avatar asked Dec 07 '15 12:12

tompa


3 Answers

A method with the router and no SwiftyJSON:

Alamofire.request(APIRouter.Register(params: params)).validate().responseJSON { response in

    switch response.result {

        case .Success(let json):
            let message = json["clientMessage"] as? String
            completion(.Success(message ?? "Success"))

        case .Failure(let error):
            var errorString: String?
            if let data = response.data {
                if let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: String] {
                    errorString = json["error"]
                }
            }
            completion(.Error(errorString ?? error.localizedDescription))
    }
}
like image 111
SoftDesigner Avatar answered Oct 22 '22 11:10

SoftDesigner


The data is not parsed in the .Failure case per the Alamofire 3.0 migration guide. However, server data is still available in response.data and can be parsed.

Below should work to parse this manually:

Alamofire.request(.POST, "https://example.com/create", parameters: ["foo": "bar"])
  .validate()
  .responseJSON { response in
     switch response.result {
     case .Success:
         print("Validation Successful")
     case .Failure(_):
          var errorMessage = "General error message"

          if let data = response.data {
            let responseJSON = JSON(data: data)

            if let message: String = responseJSON["message"].stringValue {
              if !message.isEmpty {
                errorMessage = message
              }
            }
          }

          print(errorMessage) //Contains General error message or specific.
     }
  }
}

This uses SwiftyJSON which provides the JSON struct to convert NSData. Parsing NSData to JSON can done without SwiftyJSON, answered here.

Another cleaner option might be to write a Custom Response Serializer.

like image 33
Shawn Aukstak Avatar answered Oct 22 '22 12:10

Shawn Aukstak


I have used the following lines to read the response body from a Alamofire request.

    Alamofire.request(.POST, serveraddress, headers: headers, encoding: .JSON)
        .response{ request, response, data, error in
            let responseData = String(data: data!, encoding: NSUTF8StringEncoding)
            print(responseData)


    }

With this body I can get my custom server response errormessage.

best regards

like image 36
BHuelse Avatar answered Oct 22 '22 11:10

BHuelse