{"action":"closed","issue":{"url":"https://api.github.com/repos/wvteijlingen/Spine/issues/30","labels_url":"https://api.github.com/repos/wvteijlingen/Spine/issues/30/labels{/name}","comments_url":"https://api.github.com/repos/wvteijlingen/Spine/issues/30/comments","events_url":"https://api.github.com/repos/wvteijlingen/Spine/issues/30/events","html_url":"https://github.com/wvteijlingen/Spine/issues/30","id":98589419,"number":30,"title":"Error/failure handling needs to be redesigned","user":{"login":"kurko","id":70312,"avatar_url":"https://avatars.githubusercontent.com/u/70312?v=3","gravatar_id":"","url":"https://api.github.com/users/kurko","html_url":"https://github.com/kurko","followers_url":"https://api.github.com/users/kurko/followers","following_url":"https://api.github.com/users/kurko/following{/other_user}","gists_url":"https://api.github.com/users/kurko/gists{/gist_id}","starred_url":"https://api.github.com/users/kurko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kurko/subscriptions","organizations_url":"https://api.github.com/users/kurko/orgs","repos_url":"https://api.github.com/users/kurko/repos","events_url":"https://api.github.com/users/kurko/events{/privacy}","received_events_url":"https://api.github.com/users/kurko/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-08-02T06:43:23Z","updated_at":"2015-12-16T15:41:23Z","closed_at":"2015-12-16T15:41:23Z","body":"So, I had a hard time figuring out how to return error messages so I can show them in the UI. After hours of debugging, the answer is we can't do it currently until we redesign the entire error handling logic.\r\n\r\nThis is the centralization for any work towards this goal.\r\n\r\n- [ ] **4xx-5xx aren't handled at all**\r\n\r\n  Currently, only network errors are being handled; everything else triggers `.onSuccess` (even `4xx` responses) https://github.com/wvteijlingen/Spine/issues/27\r\n\r\n  I have a fix for this in a PR, but it's impossible to unit test without a big rewrite in the `CallbackHTTPClient` object, which completely replaces the `Networking` object in tests. Instead of stubbing the server, it's stubbing the client.\r\n\r\n  To get make this rewrite not needed, we have to handle errors inside `Operations`. I believe that'd be correct because a `4xx` is not an error, it's just a decline from the server in the API negotiation. An error is an exception, such as a network error. \r\n\r\n- [ ] **Expose error response to `.onFailure` block**\r\n\r\n  Given the expectations inside the code, there's no way to return response body all the way up and expose it in the `.onFailure` block. I need to show error messages in the UI, but I can't.\r\n\r\n  We need to stop returning NSError from Networking and return our own error object, one that supports not just error code (e.g `4xx`), but the entire JSON response (not string, actual dictionary) and the JSONAPI standard.\r\n\r\n  For example, in my code, inside `Networking`'s `performRequest()`, I tried something like the following, \r\n\r\n  ```swift\r\n  var serializationErr: NSError?\r\n  var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &serializationErr) as! NSDictionary\r\n\r\n  // Trying to cramp jsonResult inside userInfo...\r\n  let userInfo = [NSLocalizedFailureReasonErrorKey: jsonResult]\r\n  operationError = NSError(domain: SpineServerErrorDomain, code: response!.statusCode, userInfo: userInfo)\r\n  ```\r\n\r\n  Inside my `.onFailure` block, I was able to output the dictionary above,\r\n  \r\n  ```\r\n  println(error.userInfo)\r\n  Optional([NSLocalizedFailureReason: {\r\n      errors =     (\r\n                  {\r\n              code = 11001;\r\n              source =             {\r\n                  pointer = \"/data/attributes/email\";\r\n              };\r\n              title = \"Value not specified.\";\r\n          }\r\n      );\r\n  }])\r\n  ```\r\n\r\n  However, when calling `println(error.localizedFailureReason)`, I get `-[__NSDictionaryI length]: unrecognized selector sent to instance 0x7ffd148788c0` because clearly a `String` was expected, not a dictionary."}}