title: How can I change the result status in Axios with an adapter?
body: <h1>The why</h1>
  
  <p>We're using the <a href="https://github.com/softonic/axios-retry" rel="noreferrer">axios-retry</a> library, which uses this code internally:</p>
  
  <p><code>axios.interceptors.response.use(null, error =&gt; {</code></p>
  
  <p>Since it only specifies the error callback, the <a href="https://github.com/axios/axios#interceptors" rel="noreferrer">Axios documentation</a> says:</p>
  
  <blockquote>
    <p>Any status codes that falls outside the range of 2xx cause this function to trigger</p>
  </blockquote>
  
  <p>Unfortunately we're calling a non-RESTful API that can return 200 with an error code in the body, and we need to retry that.</p>
  
  <p>We've tried adding an Axios interceptor before axios-retry does and changing the result status in this case; that did not trigger the subsequent interceptor error callback though.</p>
  
  <p>What <em>did</em> work was specifying a custom adapter. However this is not well-documented and our code does not handle every case.</p>
  
  <h1>The code</h1>
  
  <pre><code>const axios = require('axios');
  const httpAdapter = require('axios/lib/adapters/http');
  const settle = require('axios/lib/core/settle');
  const axiosRetry = require('axios-retry');
  
  const myAdapter = async function(config) {
    return new Promise((resolve, reject) =&gt; {
      // Delegate to default http adapter
      return httpAdapter(config).then(result =&gt; {
        // We would have more logic here in the production code
        if (result.status === 200) result.status = 500;
        settle(resolve, reject, result);
        return result;
      });
    });
  }
  
  const axios2 = axios.create({
    adapter: myAdapter
  });
  
  function isErr(error) {
    console.log('retry checking response', error.response.status);
    return !error.response || (error.response.status === 500);
  }
  
  axiosRetry(axios2, {
    retries: 3,
    retryCondition: isErr
  });
  
  // httpstat.us can return various status codes for testing
  axios2.get('http://httpstat.us/200')
    .then(result =&gt; {
      console.log('Result:', result.data);
    })
    .catch(e =&gt; console.error('Service returned', e.message));
  </code></pre>
  
  <p>This works in the error case, printing:</p>
  
  <pre>
  retry checking response 500
  retry checking response 500
  retry checking response 500
  retry checking response 500
  Service returned Request failed with status code 500
  </pre>
  
  <p>It works in the success case too (change the URL to <a href="http://httpstat.us/201" rel="noreferrer">http://httpstat.us/201</a>):</p>
  
  <pre>
  Result: { code: 201, description: 'Created' }
  </pre>
  
  <h1>The issue</h1>
  
  <p>Changing the URL to <a href="http://httpstat.us/404" rel="noreferrer">http://httpstat.us/404</a>, though, results in:</p>
  
  <pre>
  (node:19759) UnhandledPromiseRejectionWarning: Error: Request failed with status code 404
      at createError (.../node_modules/axios/lib/core/createError.js:16:15)
      at settle (.../node_modules/axios/lib/core/settle.js:18:12)
  </pre>
  
  <p>A <code>catch</code> on the <code>httpAdapter</code> call will catch that error, but how do we pass that down the chain?</p>
  
  <p>What is the correct way to implement an Axios adapter?</p>
  
  <p>If there is a better way to handle this (short of forking the axios-retry library), that would be an acceptable answer.</p>
  
  <h1>Update</h1>
  
  <p>A coworker figured out that doing <code>.catch(e =&gt; reject(e))</code> (or just <code>.catch(reject)</code>) on the <code>httpAdapter</code> call appears to handle the issue. However we'd still like to have a canonical example of implementing an Axios adapter that wraps the default http adapter.</p>