title: How to fetch response body using fetch in case of HTTP error 422?
body: <p>I have an API on backend which sends status <code>201</code> in case of a successful call and if there's
  any error with the submitted data it sends status <code>422</code> (Unprocessable Entity) with a json response like below:</p>
  <pre><code>{
    &quot;error&quot;: &quot;Some error text here explaining the error&quot;
  }
  </code></pre>
  <p>Additionally it sends <code>404</code> in case API fails to work on back end for some reason.</p>
  <p>On the front-end I'm using the below code to fetch the response and perform a success or error callback based on response status code:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>fetch("api_url_here", {
      method: 'some_method_here', 
      credentials: "same-origin",
      headers: {
        "Content-type": "application/json; charset=UTF-8",
        'X-CSRF-Token': "some_token_here"
      }
      })
    .then(checkStatus)
    .then(function json(response) {
      return response.json()
    })
    .then(function(resp){
      successCallback(resp)
    })
    .catch(function(error){
      errorCallback(error);
    });
    
  //status function used above
  checkStatus = (response) =&gt; {
    if (response.status &gt;= 200 &amp;&amp; response.status &lt; 300) {
      return Promise.resolve(response)
    } else {
      return Promise.reject(new Error(response))
    }
  }</code></pre>
  </div>
  </div>
  </p>
  <p>The <code>successCallback</code> function is able to receive the response in proper JSON format in case of status code <code>201</code> but when I try to fetch the error response in <code>errorCallback</code> (<code>status: 422</code>) it shows something like this (logging the response in console):</p>
  <pre><code>Error: [object Response]
      at status (grocery-market.js:447)
  </code></pre>
  <p>When I try to <code>console.log</code> the error response before wrapping it in <code>new Error()</code> like this,</p>
  <pre><code>  checkStatus = (response) =&gt; {
      if (response.status &gt;= 200 &amp;&amp; response.status &lt; 300) {
        return Promise.resolve(response)
      } else {
        console.log(response.json()) //logging the response beforehand
        return Promise.reject(new Error(response.statusText))
      }
    }
  </code></pre>
  <p>I get the below promise in console (the <code>[[PromiseValue]]</code> property actually contains the error text that i require)</p>
  <p><a href="https://i.stack.imgur.com/WOLIy.png" rel="noreferrer"><img src="https://i.stack.imgur.com/WOLIy.png" alt="enter image description here" /></a></p>
  <p>Can someone please explain why this is happening only in error case, even though I'm calling <code>response.json()</code> in both error and success case?</p>
  <p>How can I fix this in a clean manner?</p>
  <p><strong>EDIT:</strong>
  I found that if I create another <code>json()</code> promise on the error response I am able to get the correct error :</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>fetch("api_url_here", {
      method: 'some_method_here', 
      credentials: "same-origin",
      headers: {
        "Content-type": "application/json; charset=UTF-8",
        'X-CSRF-Token': "some_token_here"
      }
      })
    .then(checkStatus)
    .then(function json(response) {
      return response.json()
    })
    .then(function(resp){
      successCallback(resp)
    })
    .catch(function(error){
      error.json().then((error) =&gt; { //changed here
          errorCallback(error)
        });
    });</code></pre>
  </div>
  </div>
  </p>
  <p>But why do I have to call another <code>.json()</code> on the response in error case?</p>