200 OK! Error Handling in GraphQL

How to effectively model “errors” in your GraphQL schema

Image for post
Image for post
{
user(username: "@ash") {
id
name
}
}
{
"data": {
"user": {
"id": "268314bb7e7e",
"name": "Ash Ketchum"
}
}
}
{
"data": {
"user": null
},
"errors": [
{ "path": [ "user" ],
"locations": [ { "line": 2, "column": 3 } ],
"extensions": {
"message": "Object not found",
"type": 2
}
}
]
}
Image for post
Image for post

The Problem

What is an error?

Error Categories

Image for post
Image for post

Errors

Image for post
Image for post

Alternative Results

Image for post
Image for post
Image for post
Image for post

Modeling Results in the GraphQL Schema

Image for post
Image for post
Image for post
Image for post
type User {
id: ID!
name: String
}
type Suspended {
reason: String
}
type IsBlocked {
message: String
blockedByUser: User
}
type UnavailableInCountry {
countryCode: Int
message: String
}
"User, or reason we can't get one normally"
union UserResult = User | IsBlocked | Suspended
{
userResult(username: "@ash") {
__typename
... on User {
id
name
}
... on IsBlocked {
message
blockedByUser {
username
}
}
... on Suspended {
reason
}
}
{
"data": {
"userResult": {
"__typename": "User",
"id": "268314bb7e7e",
"name": "Ash Ketchum"
}
}
}
{
"data": {
"userResult": {
"__typename": "IsBlocked",
"message": "User blocked: @ash",
"blockedByUser": {
"username": "@brock"
}
}
}
}
Image for post
Image for post

Complex Schema Structures

type ProfileImage {
id: ID!
value: String
}
type Flagged {
reason: String
}
type Hidden {
message: String
}
"Image, or reason we can't get one normally"
union ImageResult = Image | Flagged | Hidden
{
userResult(username: "@ash") {
__typename
... on User {
id
name
profileImageResult {
__typename
... on Image {
id
}
... on Flagged {
reason
}
... on Hidden {
message
}
}
}
... on IsBlocked {
message
blockedByUser {
username
}
}
}
{
"data": {
"userResult": {
"__typename": "User",
"id": "268314bb7e7e",
"name": "Ash Ketchum",
"profileImageResult": {
"__typename": "Image",
"id": "982642"
}
}
}
}
{
"data": {
"userResult": {
"__typename": "User",
"id": "268314bb7e7e",
"name": "Ash Ketchum",
"profileImageResult": {
"__typename": "Flagged",
"reason": "Copyrighted image"
}
}
}
}

Results

Image for post
Image for post
Image for post
Image for post

Written by

software engineer @twitter, previously @medium. doing scala + graphql. pokemon gym leader. potato compatible. @sachee

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store