title: Handling 401 status w/ RxSwift & URLSession
body: <p>I currently have a network client that looks like the below:</p>
  
  <pre><code>class Client&lt;R: ResourceType&gt; {
  
      let engine: ClientEngineType
      var session: URLSession
  
      init(engine: ClientEngineType = ClientEngine()) {
          self.engine = engine
          self.session = URLSession.shared
      }
  
      func request&lt;T: Codable&gt;(_ resource: R) -&gt; Single&lt;T&gt; {
          let request = URLRequest(resource: resource)
  
          return Single&lt;T&gt;.create { [weak self] single in
              guard let self = self else { return Disposables.create() }
              let response = self.session.rx.response(request: request)
  
              return response.subscribe(
                  onNext: { response, data in
  
                      if let error = self.error(from: response) {
                          single(.error(error))
                          return
                      }
  
                      do {
                          let decoder = JSONDecoder()
                          let value = try decoder.decode(T.self, from: data)
                          single(.success(value))
                      } catch let error {
                          single(.error(error))
                      }
              },
                  onError: { error in
                      single(.error(error))
              })
          }
      }
  
      struct StatusCodeError: LocalizedError {
          let code: Int
  
          var errorDescription: String? {
              return "An error occurred communicating with the server. Please try again."
          }
      }
  
      private func error(from response: URLResponse?) -&gt; Error? {
          guard let response = response as? HTTPURLResponse else { return nil }
  
          let statusCode = response.statusCode
  
          if 200..&lt;300 ~= statusCode {
              return nil
          } else {
              return StatusCodeError(code: statusCode)
          }
      }
  }
  </code></pre>
  
  <p>Which I can then invoke something like</p>
  
  <pre><code>let client = Client&lt;MyRoutes&gt;()
  client.request(.companyProps(params: ["collections": "settings"]))
      .map { props -&gt; CompanyModel in return props }
      .subscribe(onSuccess: { props in
        // do something with props
      }) { error in
          print(error.localizedDescription)
  }.disposed(by: disposeBag)
  </code></pre>
  
  <p>I'd like to start handling <code>401</code> responses and refreshing my token and retrying the request.</p>
  
  <p>I'm struggling to find a nice way to do this.</p>
  
  <p>I found <a href="https://gist.github.com/danielt1263/68097ac187cd43c23945bc6c15f5cc0b" rel="nofollow noreferrer">this excellent gist</a> that outlines a way to achieve this, however I am struggling to implement this in my current client.</p>
  
  <p>Any tips or pointers would be very much appreciated.</p>