matthew-andrews/isomorphic-fetch

Calling response.json() when processing an error request (40x) returns a promise, not the data in the body

bggolding opened this issue · 6 comments

When I send an error from my restful api back to the server, I want to include a message. Flask has nice support for this and I can say:

if not token:
    return {‘message’: ‘Missing token’}, 401

I can see the data in the body of the response and content-type is application/json.

In my app I’m using isomorphic-fetch and I’m saying:

fetch('...url...')
    .then(response => {
        if (!response.ok) {
            const data = response.json();
            ...

Trouble is, data always comes out being an unresolved promise. If I poke around inside using the debugger I can see my data (it’s in [[PromiseValue]]) but I can’t get it. I've tried calling .then() on it to try to resolve it but that just seems to generate another Promise.

How is this supposed to work? This code works fine when the response isn't an error.

@bggolding
response.json() returns a Promise according to the specs that resolves with the deserialized data.

It is specified in the Body Mixin that is implemented by the Request as well as the Response object. See https://developer.mozilla.org/en-US/docs/Web/API/Body/json and https://fetch.spec.whatwg.org/#body-mixin for details.

How is this supposed to work? This code works fine when the response isn't an error.

I would expect data to always be a Promise. Could you show the code that runs when response.ok evaluates to true? It should not work if you handle it the same way.

A working example would be:

fetch('...url...')
    .then(response => {
        if (!response.ok) {
            response.json().then(data => {
                // handle data
            });
            ...

can this be closed?

I guess. Because I didn’t get a response to this issue [...].

Well did you read my response then? Because it clearly points to the documents showing that your original issue is the correct behavoir according to the specs in that .json() returns a promise. Did you try the code in my answer? Did it work for you?

I agree with @trixn86's diagnosis …