Errors
How to avoid errors on mutations by checking actions and deprecations, and how to read the errors field most mutations return.
A mutation can fail for many reasons: the object does not exist, the user is not allowed, a value is invalid. The API gives you two ways to avoid most failures and one way to read the rest.
Check the actions first
Most object types that are subject to permissions have a companion ...Actions object. It lists what the current user may do with that object, as booleans.
A Story has StoryActions. Before you call storyDelete, check that actions.delete is true:
query {
story(slug: 123) {
actions {
edit
delete
}
}
}
Watch for deprecations
Fields are sometimes deprecated, then removed. The schema marks them, and a GraphQL client shows the mark. Check regularly that the fields you use still exist: a query that names a removed field fails as a whole.
Read the errors field
Almost every mutation returns an errors field. It is a list of the errors found while running the mutation. Each entry implements the MutationError interface. Its one field, path, names the input field that caused the problem. Each mutation has its own set of possible error types, and __typename tells you which one occurred.
Ask for the field on every mutation that has it:
mutation storyBroadcast($input: StoryBroadcastInput!) {
storyBroadcast(input: $input) {
story {
id
}
errors {
__typename
... on MutationError {
path
}
}
}
}
Variables, with a story ID that does not exist:
{
"input": {
"id": "NOT_A_STORY_ID",
"recipients": ["USER_ID"]
}
}
The response names the error and the field:
{
"data": {
"storyBroadcast": {
"story": null,
"errors": [
{
"__typename": "ObjectNotFoundError",
"path": "input.id"
}
]
}
}
}
ObjectNotFoundError on input.id means the story ID was not found. Some error types carry more fields than path. To read them, add a fragment on that type. For example, TooManyRecipientsError, another possible error of storyBroadcast, also carries nRecipients.