Skip to content
Last updated: 2026-04-06
Reference

Error Handling

When you make a request to the Dxtra API, you may encounter errors. This guide explains the different types of errors and how to handle them.

HTTP Status Codes

The Dxtra API uses standard HTTP status codes to indicate the success or failure of a request.

Code Description
200 OK The request was successful
400 Bad Request Invalid request body or parameters
401 Unauthorized Missing or invalid authentication token
403 Forbidden Authenticated user lacks permission for the requested action
404 Not Found The requested resource does not exist
429 Too Many Requests Rate limit exceeded. See Rate Limits
500 Internal Server Error Unexpected server error

GraphQL Errors

When you make a request to the GraphQL API, you may receive a 200 OK status code with an errors array in the response body. This indicates an error processing your GraphQL query.

GraphQL Response Patterns

Dxtra's GraphQL API uses different response patterns depending on the operation type:

Many GraphQL actions follow a status/message/data pattern:

JSON
{
  "data": {
    "generateDataControllerDID": {
      "status": "success",
      "message": "generateDataControllerDID",
      "data": {
        "dataControllerId": "123e4567-e89b-12d3-a456-426614174000",
        "did": "did:dep:2135944ab870c8c5f44d4ca3da8550c5fbae6311318db8f9480b5dae5033d32a"
      }
    }
  }
}

Actions using this pattern:

  • generateDataControllerDID
  • generateDataSubjectDID
  • reportDataControllersComplianceIssues
  • reportDataSubjectsRightsRequests
  • loginUserTagManager

Some actions return data directly without status wrappers:

JSON
{
  "data": {
    "fetchStripeProducts": {
      "products": [
        {
          "id": "prod_123",
          "name": "Professional Plan",
          "prices": [
            {
              "id": "price_456",
              "amount": 2999,
              "currency": "usd"
            }
          ]
        }
      ]
    }
  }
}

Simple operations return minimal confirmations:

JSON
{
  "data": {
    "triggerManualReassessment": {
      "inserted": true
    }
  }
}

Always check your specific action's response format using GraphQL introspection or the Actions Reference.

Common GraphQL Error Examples

JSON
{
  "errors": [
    {
      "message": "field 'dataControllers' not found in type: 'query_root'",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["dataControllers"]
    }
  ]
}
JSON
{
  "errors": [
    {
      "message": "insufficient privilege: role 'anonymous' is missing role 'user'",
      "extensions": {
        "path": "$.selectionSet.dataControllers",
        "code": "validation-failed"
      }
    }
  ]
}
JSON
{
  "data": {
    "generateDataControllerDID": {
      "status": "error",
      "message": "Data Controller not found",
      "data": null
    }
  }
}

Error Handling Best Practices

1. Comprehensive Error Detection

JavaScript
const executeGraphQLQuery = async (query, variables = {}) => {
  try {
    const response = await fetch('https://api.dxtra.ai/v1/graphql', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${jwtToken}`,
        'X-Hasura-Role': 'user'
      },
      body: JSON.stringify({ query, variables })
    });

    // Check HTTP status first
    if (!response.ok) {
      if (response.status === 401) {
        throw new Error('AUTH_EXPIRED');
      }
      throw new Error(`HTTP_${response.status}: ${response.statusText}`);
    }

    const result = await response.json();

    // Check for GraphQL errors
    if (result.errors && result.errors.length > 0) {
      const errorMessage = result.errors[0].message;
      const errorCode = result.errors[0].extensions?.code;
      throw new Error(`GRAPHQL_ERROR: ${errorCode || 'UNKNOWN'} - ${errorMessage}`);
    }

    // For actions, check status field if present
    const actionData = Object.values(result.data || {})[0];
    if (actionData && actionData.status === 'error') {
      throw new Error(`ACTION_ERROR: ${actionData.message}`);
    }

    return result.data;

  } catch (error) {
    console.error('GraphQL query failed:', error.message);
    throw error;
  }
};

2. Retry Logic with Exponential Backoff

JavaScript
const executeWithRetry = async (operation, maxRetries = 3) => {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await operation();
    } catch (error) {
      const isRetryable = error.message.includes('HTTP_5') ||
                          error.message.includes('AUTH_EXPIRED');

      if (!isRetryable || attempt === maxRetries) {
        throw error;
      }

      // Exponential backoff: 1s, 2s, 4s
      const delay = Math.pow(2, attempt - 1) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));

      // Refresh auth token if expired
      if (error.message.includes('AUTH_EXPIRED')) {
        jwtToken = await getJwtFromApiKey(apiKey);
      }
    }
  }
};

3. User-Friendly Error Messages

JavaScript
const translateErrorForUser = (error) => {
  const errorMap = {
    'AUTH_EXPIRED': 'Your session has expired. Please refresh the page.',
    'GRAPHQL_ERROR: validation-failed': 'Invalid request. Please check your input.',
    'HTTP_429': 'Too many requests. Please wait a moment and try again.',
    'HTTP_500': 'Service temporarily unavailable. Please try again later.',
    'ACTION_ERROR': 'Operation failed. Please check your input and try again.'
  };

  for (const [pattern, message] of Object.entries(errorMap)) {
    if (error.message.includes(pattern)) {
      return message;
    }
  }

  return 'An unexpected error occurred. Please contact support if this persists.';
};

Common Error Scenarios

Error Type Cause Solution
401 Unauthorized Missing/invalid JWT token Refresh authentication
403 Forbidden Insufficient role permissions Check X-Hasura-Role header
Field not found Using wrong field names Use camelCase field names (e.g., dataControllers)
Rate limit exceeded Too many requests Implement exponential backoff
Action status: error Business logic failure Check action-specific error message

Monitoring and Debugging

Request/Response Logging

JavaScript
if (process.env.NODE_ENV === 'development') {
  console.log('GraphQL Request:', { query, variables });
  console.log('GraphQL Response:', result);
}

Production Error Tracking

For production applications, implement proper error monitoring:

  • Sentry -- Automatic error tracking and performance monitoring
  • LogRocket -- Session replay for debugging user issues
  • Custom logging -- Log API errors with context for debugging

Rate Limiting

Webhook endpoints are rate limited to 1000 requests per 15 minutes per IP. GraphQL actions called via the API are not rate limited. See Rate Limits for details.