How to achieve GraphQL Error Handling for Multiple Items?

Viewed 155

I have been learning GraphQL and right now I am learning things related to Error Handling in GraphQL. I referred to this article for Error Handling in GraphQL. Now, from Article I understand that If I have a user query in GraphQL then I can make an Union which will contain all possible types including Error

union UserResult = User | DeletedUser | Error

Now, In that particular resolver if any error would occur then I will send an Error type Response and I'll be able to show appropriate error on Client Side. and Thats the Error Handling.

But what If I have a query users which will return an Array of Users. Suppose by following the above approach I will be doing something like...

type Query {
         users: [UserResult!]!
}

union UserResult = User | DeletedUser | Error

Now, In users resolver if any error would occur then I wont be able to send back a single Error Response. Because, GraphQL does not allow such syntax...

type Query {
         users: UsersResult!
}

union UserResult = User | DeletedUser | Error
union UsersResult = [UserResult!] | Error

So, How am I gonna achieve this functionality in GraphQL?

The Response I expect is...

If nothing goes wrong...


data: {
    users: [
        { id: '1', username: 'user1', email: 'user1@demo.com' },
        { id: '2', username: 'user2', email: 'user2@demo.com' },
        { id: '3', username: 'user3', email: 'user3@demo.com' }
    ]
}

If something goes wrong while fetching data from database(for instance)...

data: {
    error: {
        code: 'ER101',
        message: 'Something went wrong',
    }
}
2 Answers

I would do something like this, to keep the benefits explained in the article:

union UserResult = User | DeletedUser | Error

type UserList {
  list: [UserResult!]!
  count: Int
}

union UsersResult = UserList | Error

type Query {
  users: UsersResult!
}

You can then handle errors like this:

query users {
  users {
    ...on UserList {
      count
      list {
        ...on User {
          name
        }
        ...on DeletedUser {
          code
        }
        ...on Error {
          code
        }
      }
    }
    ...on Error {
      code
    }
  }
}

It also depends on your use cases and business logic.

Not sure if this will solve your case:

// User type:
user: {
    id: string,
    username: string,
    email: string,
}

// Return type looks like this:
data: {
    users: user[] | null, // nullable
    error: {
        code: string,
        message: string,
    } | null // nullable
}

// If nothing went wrong:
data: {
    users: [
        { id: '1', username: 'user1', email: 'user1@demo.com' },
        { id: '2', username: 'user2', email: 'user2@demo.com' },
        { id: '3', username: 'user3', email: 'user3@demo.com' }
    ],
    error: null,
}

// If something went wrong:
data: {
    users: null,
    error: {
        code: 'ER101',
        message: 'Something went wrong',
    }
}

It's up to your use case, since your users is an array, and error only contains one message, I suppose errors can be concluded to one single error and inform client?

Related