title: Alamofire 5 RequestInterceptor, How to retry request without needing to use .validate() for token refresh?
body: <p>I'm re-writing the networking in my app with alamofire 5 (rc3) and I'm trying to retry the request if it fails due to my JWT token being expired, I can get this to work if I simply tag a <code>.validate()</code> onto the request meaning the API 401 response causes the request to 'fail' and then be passed to the <code>RequestRetrier</code>, however every other 400-499 request my API returns data in the same form and the <code>message</code> is useful but by using <code>.validate()</code> it throws away the useful object-ifying that .decodeResponse() gives:</p>
  
  <pre><code>{
      "data": null,
      "message": "Token has expired",
      "status": "error"
      /* has 401 error code */
  }
  </code></pre>
  
  <pre class="lang-swift prettyprint-override"><code>class NetworkInterceptor: RequestInterceptor {
  
      // MARK: - RequestAdapter
      func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result&lt;URLRequest, Error&gt;) -&gt; Void) {
          print("adapting")
          var adaptedRequest = urlRequest
          let token = NetworkService.sharedInstance.authToken
          adaptedRequest.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
          completion(.success(adaptedRequest))
      }
  
  
      // MARK: - RequestRetrier
      func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -&gt; Void) {
          if let response = request.task?.response as? HTTPURLResponse, let WWWheader = response.allHeaderFields["Www-Authenticate"] as? String, response.statusCode == 401, WWWheader == "Bearer realm=\"everywhere\"" {
              print("Refreshing token for retry...")
              NetworkService.sharedInstance.refreshTokens { (success, _, _) in
                  print("Refreshed token, retrying request")
                  completion(.retry)
              }
          } else {
              completion(.doNotRetry)
          }
      }
  
  }
  </code></pre>
  
  <p>An example function to call my API inside my network manager looks like as follows, session is just the normal session with the Network interceptor attached (and working).</p>
  
  <p>A typical API call function looks like this:</p>
  
  <pre class="lang-swift prettyprint-override"><code>func sendMove(id: Int, move: Move, completion: @escaping APICompletionHandler&lt;GameRender&gt;) {
      session.request(APIRouter.sendMove(id: id, move: move)).responseDecodable { (response: DataResponse&lt;APIResponse&lt;GameRender&gt;, AFError&gt;) in
          switch response.result {
          case .success(let apiResponse):
              if apiResponse.status == .success {
                  // Data from API and success
                  completion(true, apiResponse.data, apiResponse.message)
              } else {
                  // Data from API but not success
                  completion(false, apiResponse.data, apiResponse.message)
              }
          case .failure(let data):
              // Could not get anything from API
              completion(false, nil, data.localizedDescription)
          }
      }
  }
  </code></pre>
  
  <p>You can see I return some form of error response inside case .success(let apiResponse) if the body's "success" key is false. This however means the request is never put to the requestRetrier</p>
  
  <p>If however I use .validate()</p>
  
  <pre class="lang-swift prettyprint-override"><code>func sendMove(id: Int, move: Move, completion: @escaping APICompletionHandler&lt;GameRender&gt;) {
      session.request(APIRouter.sendMove(id: id, move: move)).validate().responseDecodable { (response: DataResponse&lt;APIResponse&lt;GameRender&gt;, AFError&gt;) in
          switch response.result {
          case .success(let apiResponse):
              if apiResponse.status == .success {
                  // Data from API and success
                  completion(true, apiResponse.data, apiResponse.message)
              } else {
                  // Data from API but not success
                  // NOW THIS NEVER RUNS
                  completion(false, apiResponse.data, apiResponse.message)
              }
          case .failure(let data):
              // Could not get anything from API
              completion(false, nil, data.localizedDescription)
          }
      }
  }
  </code></pre>
  
  <p>You can now see that the <code>else{}</code> in the first portion of the switch never gets run. These two patterns seem to be at odds, is there a way of calling retry on a specific call, after parsing, for example 
  <code>if (token needs refreshing?) -&gt; retry this request</code></p>