2

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',
    }
}
D_Gamer
  • 168
  • 12
  • What kind of error you'd like to invoke and send back? Can you describe the error object? From where I can understand, you can send error response like this `{ data: { user: null, deletedUser: null, error: { someField: "myfield", msg: "message to ui" }} }` – Enfield Li May 15 '22 at 08:23
  • @Enfieldli I have updated the question with my expected Response. – D_Gamer May 22 '22 at 11:53

2 Answers2

2

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.

Martin Schaer
  • 3,986
  • 1
  • 23
  • 28
0

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?

Enfield Li
  • 1,952
  • 1
  • 8
  • 23
  • This was already in my mind, but I have mentioned an article in my Question that I referred for understanding Error Handling in GraphQL and which I found pretty convincing and logical. Your answer will definitely solve the Problem but still it will be just a workaround. Can you please look at that article, maybe you can solve the problem using the method explained in there. Also Thanks for the reply. – D_Gamer May 22 '22 at 12:24
  • I'm sorry, too advanced hahah, but setting up different user attributes seems like a good approach to it – Enfield Li May 22 '22 at 12:43