Skip to main content
GraphQL Basics
CHAPTER 17 Beginner

Error Handling in GraphQL

Updated: May 13, 2026
20 min read

# CHAPTER 17

Error Handling in GraphQL

1. Introduction

In a standard REST API, developers rely heavily on HTTP Status Codes. If a user is not found, the server returns a 404 Not Found. If a server crashes, it returns a 500 Internal Server Error. GraphQL approaches errors entirely differently. In this chapter, we will learn why GraphQL almost always returns a 200 OK HTTP status, how the standardized errors array works, and how to format validation and execution errors for the frontend client.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Explain why GraphQL responses usually return an HTTP 200 status code even when errors occur.
  • Understand the structure of the GraphQL JSON response (Data vs. Errors).
  • Throw exceptions in PHP resolvers and see them appear in the GraphQL response.
  • Differentiate between Syntax errors, Validation errors, and Execution errors.

3. Beginner-Friendly Explanation

Imagine ordering food through a delivery app. In a REST API, if one item (e.g., the fries) is sold out, the restaurant cancels the entire order and sends you a message: "Error: Order Failed" (HTTP 404/500).

In GraphQL, the restaurant is much more accommodating. If you order a Burger, Fries, and a Drink, and the fries are sold out, the restaurant still delivers the Burger and the Drink. In the bag, they include a note: "Here is your food (Data). By the way, we couldn't give you the fries (Error)." Because the delivery itself was successful, the delivery driver logs it as a success (HTTP 200 OK), but the payload contains both partial data and an error message.

4. Real-World Examples

  • Partial Data Fetching: A dashboard queries for a user's Profile, their latest Orders, and their social media feed. The social media API is down. GraphQL returns the Profile and Orders data successfully, but includes an error message specifically attached to the feed field.
  • Form Validation: A user tries to sign up with an invalid email. The mutation returns an error array specifically highlighting the email field validation failure.

5. The Response Structure

A GraphQL response JSON has a strict standard. It can contain a data key, an errors key, or both.

Example of an Error Response:

json
123456789101112131415
{
  "data": {
    "user": {
      "name": "Jane",
      "friends": null
    }
  },
  "errors": [
    {
      "message": "Database connection failed for friends table.",
      "locations": [ { "line": 4, "column": 5 } ],
      "path": [ "user", "friends" ]
    }
  ]
}

Notice how the path tells the frontend exactly which field caused the error!

6. Throwing Errors in PHP Resolvers

When you are writing your backend code, how do you trigger these errors? You simply throw standard Exceptions. The GraphQL engine catches them and formats them automatically.
php
123456789101112
'changePassword' => [
    'type' => Type::boolean(),
    'args' => ['newPass' => Type::string()],
    'resolve' => function ($root, $args, $context) {
        if (strlen($args[&#039;newPass']) < 8) {
            // This Exception is caught by GraphQL
            throw new \Exception("Password must be at least 8 characters long.");
        }
        
        return updatePassword($args[&#039;newPass']);
    }
]

7. Types of Errors

  1. 1. Syntax Errors: The client sent a badly formatted query (e.g., missing a curly brace). The server rejects it immediately.
  1. 2. Validation Errors: The syntax is fine, but the query asks for a field that does not exist in the Schema, or passes a String to an Int argument. Rejected immediately.
  1. 3. Execution Errors: The query is valid, but something went wrong while running the resolver (e.g., database offline, validation failed, unauthorized).

8. Customizing Error Formatting (Advanced)

By default, PHP Exceptions might leak sensitive file paths or database queries to the frontend. You should configure your GraphQL server to format errors cleanly.
php
12345678910111213
use GraphQL\Error\FormattedError;

// In your execution block
try {
    $result = GraphQL::executeQuery($schema, $query);
    $output = $result->toArray(true); // 'true' enables debug info in dev
} catch (\Exception $e) {
    $output = [
        &#039;errors' => [
            FormattedError::createFromException($e)
        ]
    ];
}

9. Best Practices

  • Do not rely on HTTP Status Codes: Frontend developers must check if the errors array exists in the JSON response, rather than just checking if response.status === 200.
  • Use Union Types for Business Errors: For things like Form Validation (Invalid Email, Password too short), it is often better to return a custom object in the data payload rather than throwing a hard exception. (e.g., returning a UserUpdateResult which could be a User or a ValidationError).
  • Hide Stack Traces in Production: Ensure that detailed PHP stack traces are disabled in production to prevent security leaks.

10. Common Mistakes

  • Crashing the Server: If your PHP code encounters a fatal error or a syntax error, it might return a 500 status with an HTML response. Ensure all PHP errors are caught and transformed into JSON for GraphQL.
  • Ignoring Nullability: If a resolver throws an error for a field, that field returns null. If the schema marks that field as Non-Null (!), the error bubbles up to the parent object, nullifying the parent too. Be careful with ! in schemas.

11. Mini Exercises

  1. 1. If a query successfully fetches a User, but fails to fetch their Orders, what HTTP status code will the server likely return?
  1. 2. What are the two primary root keys in a GraphQL JSON response?

12. Coding Challenges

Challenge 1: You are writing a resolver for getUser(id: ID!). The user is not found in the database. Write the PHP code inside the resolver to trigger a GraphQL error with the message "User not found."

13. MCQs with Answers

Question 1

Why does a GraphQL API generally return an HTTP 200 OK status even when an error occurs?

Question 2

How do you trigger an Execution Error inside a PHP resolver?

Question 3

Which property in the errors array tells the frontend exactly which field in the query failed?

14. Interview Questions

  • Q: Contrast how REST and GraphQL handle a scenario where a requested resource is not found.
  • Q: Explain the concept of "Partial Responses" in GraphQL.
  • Q: If an error occurs in a field marked as Non-Null (!) in the schema, what happens to the JSON response?

15. FAQs

Q: Can I force GraphQL to return a 400 or 500 HTTP code? A: Yes. If the query fails validation before execution even begins, you can manually configure your PHP script to set an HTTP 400 status. However, standard execution errors are usually kept as 200s.

16. Summary

In this chapter, we decoded GraphQL's unique approach to Error Handling. We learned that GraphQL prioritizes delivering as much data as possible, leading to partial responses where valid data is returned alongside an errors array, all under a 200 OK HTTP status. We also saw how throwing standard Exceptions in backend resolvers automatically populates this errors array, complete with the exact path to the failing field.

17. Next Chapter Recommendation

We have covered all the theory, syntax, security, and error handling. It is time to put it all together. Proceed to Chapter 18: Building GraphQL APIs with PHP where we will architect a complete, professional backend structure.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·