Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to handle HTTP error with combination of valid graphql response #5886

Open
SumeraMartin opened this issue May 14, 2024 · 5 comments
Open

Comments

@SumeraMartin
Copy link

Question

Hi,

We found an interesting situation where I'm not sure if it is a missing feature in the Apollo Kotlin client or if we just haven't found the answer.

Our backend currently has a feature where it returns HTTP status codes (401, 429, 500, etc.) along with a valid GraphQL response. This does not seem to be an issue for the iOS client, React client, etc., but for the Kotlin client, it appears to be problematic. When the response is not 2XX, an ApolloHttpException is thrown, and there is no data in response.data nor errors in response.errors. I was able to overcome this issue by changing the status code of the HTTP response in an OkHttp interceptor so that the body is still parsed.

According to the documentation for GraphQL routers, this is a valid response. For example, here: Apollo GraphQL Router Customizations

fn supergraph_service(service) {
    // Define a closure to process our request
    let f = |request| {
        // Something goes wrong during request processing...
        throw #{
            status: 403,
            body: #{
                errors: [#{
                    message: `I have raised a 403`,
                    extensions: #{
                        code: "ACCESS_DENIED"
                    }
                }]
            }
        };
    };
    // Map our request using our closure
    service.map_request(f);
}

However, it seems that the Kotlin client doesn't allow processing such requests, and without some "hacks," you cannot access the GraphQL body response when an HTTP code outside the 2XX range is received. How can this problem be solved without "hacks"?

Thank you.

@martinbonnin
Copy link
Contributor

Hi 👋 You've just bumped into a loophole of GraphQL, congrats!
The HTTP transport is not specified at the moment (a draft is here though) and it's hard to align implementations.

I'll look into what it takes to let some errors pass through but this might take a while to settle on this. In the short term, your solution is good 👍

Out of curiosity, when the error code is not 2XX, do you have data != null? Or just errors != null

@SumeraMartin
Copy link
Author

both data and errors are null

@martinbonnin
Copy link
Contributor

Sorry, I meant in your backend response.

Does your server return != 2XX together with some data? The GraphQL over HTTP spec seems to go towards not allowing this (although I'll need to reread that several times since it also looks like it depends the content-type)

@SumeraMartin
Copy link
Author

I see, it will return only error and according they understanding of graphql specification which should be active from 1.1.2025 they will return just errors with no data at all. As shown in example:

body: #{
    errors: [#{
        message: `I have raised a 403`,
        extensions: #{
            code: "ACCESS_DENIED"
        }
    }]
}

@martinbonnin
Copy link
Contributor

they will return just errors with no data at all

Gotcha 👍 Yep, that makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants