Handling GraphQL Errors

1. Throwing Errors in Resolvers

Example: Throw GraphQLError

import { GraphQLError } from "graphql";

throw new GraphQLError("User not found", {
  extensions: { code: "NOT_FOUND", http: { status: 404 } }
});

2. Using GraphQLError Class

OptionDetail
messageHuman-readable description
extensions.codeMachine-readable error code
extensions.http.statusOverride HTTP status (Yoga/v4)
originalErrorUnderlying error to wrap
path / locationsSet automatically

3. Adding Error Extensions

Example: Rich extensions

{
  "errors": [{
    "message": "Validation failed",
    "extensions": {
      "code": "BAD_USER_INPUT",
      "field": "email",
      "constraint": "format"
    }
  }]
}

4. Formatting Error Responses

Example: formatError hook

const server = new ApolloServer({
  schema,
  formatError: (formatted, error) => {
    if (formatted.extensions?.code === "INTERNAL_SERVER_ERROR") {
      return { message: "Internal error", extensions: { code: "INTERNAL_SERVER_ERROR" } };
    }
    return formatted;
  }
});

5. Handling Validation Errors

TypeCode
Schema validationGRAPHQL_VALIDATION_FAILED
Input validationBAD_USER_INPUT
Variable typeGRAPHQL_VALIDATION_FAILED

6. Handling Authentication Errors

Example: 401-style error

throw new GraphQLError("Authentication required", {
  extensions: { code: "UNAUTHENTICATED", http: { status: 401 } }
});

7. Handling Authorization Errors

Example: 403-style error

throw new GraphQLError("Insufficient permissions", {
  extensions: { code: "FORBIDDEN", http: { status: 403 }, requiredRole: "ADMIN" }
});

8. Handling Not Found Errors

ApproachWhen
Return nullLookup-style query (preferred)
Throw NOT_FOUNDMutation targeting nonexistent record
Error unionWhen typed errors are part of the API

9. Masking Internal Errors

RiskMitigation
Stack trace leakDisable in production formatError
DB error messagesCatch and re-throw generic message
Path leakStrip path from masked errors

10. Logging Errors

FieldLog
requestIdCorrelate to request
operationNameIdentify query
pathWhere in tree
originalError.stackServer-only
user.idFor auditing

11. Returning Partial Data

BehaviorDetail
Failed nullable field → nullOther fields succeed
Errors array populatedOne entry per failed field with path
HTTP 200Even with errors (per spec)

12. Using Error Codes

CodeMeaning
UNAUTHENTICATEDMissing/invalid credentials
FORBIDDENAuthenticated but not allowed
BAD_USER_INPUTInvalid input
NOT_FOUNDResource missing
CONFLICTState conflict (duplicate, version mismatch)
RATE_LIMITEDToo many requests
INTERNAL_SERVER_ERRORUnexpected failure
GRAPHQL_VALIDATION_FAILEDQuery invalid against schema
PERSISTED_QUERY_NOT_FOUNDAPQ miss