Skip to content

Error while multiple mutations stop execution #346

@maximecolin

Description

@maximecolin
Q A
Bug report? maybe
Feature request? maybe
BC Break report? no
RFC? no
Version/Branch 0.11.1

Hi. I'm experiencing a strange behavior and I'm not sure it's normal or not.

When I perform multiple queries in the same http request and one of the queries failed (typically, the resolver throw an exception),

{
   fail: Foobar(uuid: "abc") { uuid }
   success: Foobar(uuid: "efg") { uuid }
}

then two possible case :

  • my query return type is not-nullable, then the resolution is stoped and my response will contain an empty data and 1 error.
{
   "errors": [{ "message": "Foobar error", "path": ["fail"] }],
   "data": []
}
  • or, my query return type is nullable, then the resolution continue and my response will contain the data of the others queries, 1 null data and 1 error for the failed queries.
{
   "errors": [{ "message": "Foobar error", "path": ["fail"] }],
   "data": {
        "fail": null,
        "success": { "uuid": "efg" }
   }
}

I thought i will have the same behavior with multiple mutation but when one of the mutations failed the others ones are not resolved, no matter the return types are nullable or not.

mutation {
   fail: CreateFoobar(uuid: "abc") { uuid }
   success: CreateFoobar(uuid: "efg") { uuid }
}

With not nullable return type :

{
   "errors": [{ "message": "Foobar error", "path": ["fail"] }],
   "data": []
}

With nullable return type :

{
   "errors": [{ "message": "Foobar error", "path": ["fail"] }],
   "data": {
        "fail": null,
        "success": null
   }
}

The second mutation is not executed.

What i expect :

{
   "errors": [{ "message": "Foobar error", "path": ["fail"] }],
   "data": {
        "fail": null,
        "success": { "uuid": "efg" }
   }
}

I read this article about mutations and this seems to match what i expect :

Also keep in mind the difference between the nullable and not-null mutation field types. According to the GraphQL error propagation rules, if an error is raised during the resolution of a not-null field, then the whole object is considered unresolved and the error bubbles up. Since mutation fields are always resolved sequentially, this provides us a mechanism to control how mutation query execution should react in case of a failed mutation field.

In our case we decided to make all top-level mutation fields nullable. This means that if one mutation field fails for some reason, then subsequent sibling mutation fields will still execute.

An alternative would be to disallow this behaviour and make all fields not-null. In this case query execution will stop on the first failed mutation field. Yet another alternative would be to allow client to decide the error handling behaviour and provide both field variations in the schema.

If i understand correctly, in case of multiple mutations, if return types are not nullable, the execution will stop a the first error, if return types are nullable, the execution will continue and all mutations will be processed, which is not the case currently.

Can you tell me what behavior is the right one ? Is it possible to execute all mutations event if one of them raise an exception ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions