title: How to generate and handle errors in Swift
body: <p>I'm working on an app where users need to login. The webapplication uses a token, that users can get from calling a webservice using their username and password. My question now is what's the best way the handle errors that can occur. What I have now:</p>
  
  <p>LoginViewController.swift</p>
  
  <pre><code>self.api.token(forUsername: "a", password: "b") { (result) in
      switch (result) {
      case .failure(let error):
          print("something when wrong \(error)")
      case .success(let token):
          print("token \(token)")
  }
  </code></pre>
  
  <p>LoginAPIClient (the self.api) using <a href="https://github.com/3lvis/Networking" rel="nofollow noreferrer">https://github.com/3lvis/Networking</a></p>
  
  <pre><code>class LoginAPIClient {
  
  enum ResponseError: Error {
      case unexpectedDataError
      case unknownError
  }
  
  enum Result {
      case success(String)
      case failure(Error)
  }
  
  lazy var networking: Networking = {
      let networking = Networking(baseURL: APIClient.serverURL())
      return networking
  }()
  
  func token(forUsername username: String, password: String, completion: @escaping (Result) -&gt; Void) {
      let parameters = ["username" : username, "password" : password]
      networking.post("/api/login", parameters: parameters) { (result) in
          switch result {
          case .failure(let response):
              return completion(.failure(response.error))
          case .success(let response):
              if var token = response.headers["Authorization"] as? String {
                  token = token.replacingOccurrences(of: "Bearer ", with: "")
                  return completion(.success(token))
              }
              return completion(.failure(ResponseError.unknownError))
          }
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Here for example I'm creating my own error <code>return completion(.failure(ResponseError.unknownError))</code> in case the server responds with a successful status code (200) but somehow the Authorization header is missing from the response.</p>
  
  <p>This works, the only problem is that now when I handle the error in the ViewController I don't know the exact reason why it fails. For example, from the Networking library I get an error code (400 or 401 etc) but this is lost because first it was an NSError. I could use an NSError but somehow this doesn't feel right. Could anyone point me in the right direction?</p>
  
  <p>One of the solutions I thought of was to add an extra enum and then do something like this:</p>
  
  <pre><code>enum Result {
      case success(String)
      case networkFailure(FailureJSONResponse)
      case failure(Error)
  }
  
  self.api.token(forUsername: "a", password: "b") { (result) in
  switch (result) {
  case .failure(let error):
      print("something when wrong \(error)")
  case .networkFailure(let response):
      print("something when wrong \(error)")
  case .success(let token):
      print("token \(token)")
  </code></pre>
  
  <p>}</p>
  
  <p>But I rather have just 1 success and 1 failure in the switch.</p>