Error Handling
This chapter describes how errors are returned in GraphQL responses and how to handle them.
Error response structure
GraphQL errors are returned in the errors array of the response. Each error contains:
{
"errors": [
{
"message": "Entity not found",
"locations": [
{
"line": 3,
"column": 5
}
],
"path": ["runtime", "industryEnergyEnergyMeter", "items"],
"extensions": {
"code": "ENTITY_NOT_FOUND",
"details": "No entity found with rtId: 65dc6d24cc529cdc46c84fcc"
}
}
],
"data": null
}
Error fields
| Field | Description |
|---|---|
message | Human-readable error description |
locations | Position in the GraphQL query where the error occurred |
path | Path to the field that caused the error |
extensions.code | Machine-readable error code |
extensions.details | Additional error details |
Partial responses
GraphQL can return partial data alongside errors. If some parts of a query succeed while others fail, you may receive both data and errors:
{
"errors": [
{
"message": "Access denied to field 'configuration'",
"path": ["runtime", "systemCommunicationMeshAdapter", "items", 0, "configuration"]
}
],
"data": {
"runtime": {
"systemCommunicationMeshAdapter": {
"items": [
{
"rtId": "65d5c447b420da3fb12381bc",
"name": "My Adapter",
"configuration": null
}
]
}
}
}
}
Common error codes
Query errors
| Code | Description |
|---|---|
ENTITY_NOT_FOUND | The requested entity does not exist |
TYPE_NOT_FOUND | The specified ckTypeId is not valid |
INVALID_FILTER | Filter parameters are invalid |
INVALID_SORT | Sort parameters are invalid |
INVALID_CURSOR | Pagination cursor is invalid or expired |
Mutation errors
| Code | Description |
|---|---|
VALIDATION_ERROR | Input data failed validation |
REQUIRED_FIELD_MISSING | A required field was not provided |
INVALID_FIELD_VALUE | Field value does not match expected type or format |
ENTITY_ALREADY_EXISTS | Entity with given identifier already exists |
REFERENCE_NOT_FOUND | Referenced entity (e.g., in association) not found |
CONSTRAINT_VIOLATION | Operation violates a constraint (e.g., multiplicity) |
Authorization errors
| Code | Description |
|---|---|
UNAUTHORIZED | Authentication required |
FORBIDDEN | Insufficient permissions for the operation |
ACCESS_DENIED | Access to specific resource denied |
Handling errors in code
TypeScript/JavaScript example
const response = await client.query({ query: GET_ENERGY_METERS });
if (response.errors) {
for (const error of response.errors) {
console.error(`Error: ${error.message}`);
if (error.extensions?.code === 'ENTITY_NOT_FOUND') {
// Handle missing entity
} else if (error.extensions?.code === 'FORBIDDEN') {
// Handle permission error
}
}
}
if (response.data) {
// Process successful data
}
Checking for partial success
const response = await client.mutate({
mutation: CREATE_ENTITIES,
variables: { entities: [...] }
});
// Check if any entities were created despite errors
const createdEntities = response.data?.runtime?.myEntities?.create ?? [];
const failedCount = entities.length - createdEntities.length;
if (response.errors && failedCount > 0) {
console.warn(`${failedCount} entities failed to create`);
}
Validation errors
Validation errors typically include details about which field failed and why:
{
"errors": [
{
"message": "Validation failed",
"extensions": {
"code": "VALIDATION_ERROR",
"validationErrors": [
{
"field": "voltage",
"message": "Value must be between 0 and 500"
},
{
"field": "name",
"message": "Name must not be empty"
}
]
}
}
]
}
Best practices
- Always check for errors: Even successful-looking responses may contain partial errors
- Use error codes: Match on
extensions.coderather than parsing error messages - Handle partial data: Process any valid data returned alongside errors
- Log error details: Include
pathandextensionsin logs for debugging - User-friendly messages: Map error codes to localized user-facing messages
- Retry transient errors: Network or timeout errors may succeed on retry