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

HTTP Status 200 when a mutation fails #142

Closed
ghost opened this issue Apr 7, 2016 · 5 comments
Closed

HTTP Status 200 when a mutation fails #142

ghost opened this issue Apr 7, 2016 · 5 comments

Comments

@ghost
Copy link

ghost commented Apr 7, 2016

I'm using graphene.contrib.django

If I raise an exception inside a mutation's mutate_and_get_payload() (e.g. because of a failed data validation), the resulting http response's code is 200 (OK). I'd expect 400 (Bad request).

@mjtamlyn
Copy link
Contributor

As far as I can tell from the GraphQL spec there is no discussion of http response codes at all. The status codes of HTTP are strongly tied to rest principles. It's not clear to me whether GraphQL APIs should distinguish between 2XX and 4XX status codes.

Most notably, you can batch multiple mutations into the same request to the server. If one successfully creates a resource (201), one mutates a resource (200), one fails validation (400) and another the target object does not exists (404), what should the return value from the API be?

At the moment, GraphQL APIs seem to err on the side of 200 unless the server blows up, in which case 500.

@ghost
Copy link
Author

ghost commented Jun 1, 2016

Thank you for your answer. I'm convinced.

@ghost ghost closed this as completed Jun 1, 2016
ozanmakes added a commit to ozanmakes/ocaml-graphql-server that referenced this issue Jul 5, 2018
With this commit:
- Errors get reported with 200 status code
  GraphQL spec has no mention of error codes since it doesn't care about
  the transport and uses the `error` field in the response as the source
  of truth for errors. If I'm understanding the common practice
  correctly, clients only expect HTTP error codes when the GraphQL
  server cannot answer the query at all.

  On top of this, GraphQL servers are also expected to return both
  `data` and `error` fields when it can resolve some of the queries but
  not the others, making the current 500 code too broad.

  Some references:
    graphql-python/graphene#142
    https://platform.github.community/t/http-status-codes-for-requests/1860

- Errors are returned as a JSON object
  Cohttp's respond_error utility adds the "Error:" prefix to the
  response, making it harder for the client to parse the result.
@helpse
Copy link

helpse commented Jul 25, 2018

@mjtamlyn I agree with you.
However, sometimes you want to send a 401 Unauthorized or a 403 Forbidden. Under these circumstances, graphene should send a 401/403 HTTP status.

@lsdsjy
Copy link

lsdsjy commented Jan 26, 2019

@helpse I think HTTP status code represents the status of the HTTP response itself, but not something related to the GraphQL query in the payload of the HTTP request. The request is handled perfectly by the server, that's what 200 means. And the errors in the queries? It's GraphQL's business to point them out in the response content, but not somewhere else which should be controlled by the Web Server itself. After all, the GraphQL query is only handled by only an endpoint of the server. And I think it's one of the disadvantages of GraphQL against RESTful.

@eolinlovecraft
Copy link

I understood that GraphQL doesn't care of the http codes but I have not found the way that Graphene return "extensions" in errors responses like in others

{
	"errors":[
	{
		"message":"Authentication failure!!",
		"locations":[{"line":2,"column":3}],
		"path":["me"]
	}
  ],
	"data":
	{
		"me":null
	}
}

with key "extensions":

{
  "errors": [
    {
      "message": "Name for character with ID 1002 could not be fetched.",
      "locations": [ { "line": 6, "column": 7 } ],
      "path": [ "hero", "heroFriends", 1, "name" ],
      "extensions": {
        "code": "CAN_NOT_FETCH_BY_ID",
        "timestamp": "Fri Feb 9 14:33:09 UTC 2018"
      }
    }
  ]
}

I rise exceptions with GraphQLError:

class Query(graphene.ObjectType):
    me = graphene.Field(UserType)

    def resolve_me(root, info):
        user = info.context.user
        if user.is_anonymous:
            raise GraphQLError('Authentication failure!!')
        return user

is it supported?
thanks.

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

No branches or pull requests

4 participants