Error Handling
This guide covers error handling best practices and provides comprehensive information about error codes, troubleshooting steps, and recovery strategies for Link Tracker APIs.
Error Response Format
All Link Tracker APIs return errors in a consistent format:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error description",
"details": [
{
"field": "fieldName",
"message": "Field-specific error message"
}
],
"requestId": "req_123456789",
"timestamp": "2025-11-20T17:00:00.000Z"
}
}
Error Response Fields
- code (string): Machine-readable error code for programmatic handling
- message (string): Human-readable error description
- details (array, optional): Field-level validation errors
- requestId (string): Unique identifier for tracking this request
- timestamp (string): ISO 8601 timestamp when the error occurred
HTTP Status Codes
Link Tracker uses standard HTTP status codes to indicate the success or failure of requests:
2xx Success
- 200 OK - Request succeeded
- 201 Created - Resource created successfully
- 202 Accepted - Request accepted for processing
4xx Client Errors
- 400 Bad Request - Invalid request format or parameters
- 401 Unauthorized - Invalid or missing authentication (handled by Dashboard/Auth Server)
- 404 Not Found - Resource not found
- 409 Conflict - Resource conflict (e.g., duplicate)
- 422 Unprocessable Entity - Validation errors
- 429 Too Many Requests - Rate limit exceeded (handled by Dashboard/Auth Server)
Note:
- Authentication (401) and Rate Limiting (429) are handled by the Link Dashboard's Auth Server
- 403 (Forbidden) is not currently implemented (no RBAC/permissions)
- Link Tracker service itself returns: 400, 404, 409, 422, and 5xx errors
5xx Server Errors
- 500 Internal Server Error - Unexpected server error
- 502 Bad Gateway - Upstream service error
- 503 Service Unavailable - Service temporarily unavailable
- 504 Gateway Timeout - Request timeout
Common Error Codes
Authentication Errors
INVALID_API_KEY
HTTP Status: 401
Description: The provided API key is invalid or has been revoked.
{
"error": {
"code": "INVALID_API_KEY",
"message": "The API key provided is invalid"
}
}
Resolution:
- Verify your API key is correct
- Check if the API key has been revoked
- Ensure you're using the correct environment (sandbox vs production)
TOKEN_EXPIRED
HTTP Status: 401
Description: The JWT token has expired and needs to be refreshed.
{
"error": {
"code": "TOKEN_EXPIRED",
"message": "Access token has expired"
}
}
Resolution:
- Use your refresh token to obtain a new access token
- Implement automatic token renewal in your application
- Note: Token refresh is handled by the Dashboard Auth Server
Validation Errors
INVALID_REQUEST
HTTP Status: 400
Description: Request format or required parameters are invalid.
{
"error": {
"code": "INVALID_REQUEST",
"message": "Request validation failed",
"details": [
{
"field": "limit",
"message": "Limit must be a positive number"
},
{
"field": "sortOrder",
"message": "Sort order must be 'asc' or 'desc'"
}
]
}
}
Resolution:
- Review the API documentation for correct parameter formats
- Check the
detailsarray for specific field errors - Ensure all required fields are provided
INVALID_DATE_FORMAT
HTTP Status: 400
Description: Date parameters are not in the correct ISO 8601 format.
{
"error": {
"code": "INVALID_DATE_FORMAT",
"message": "Date must be in ISO 8601 format"
}
}
Resolution:
- Use ISO 8601 format:
YYYY-MM-DDTHH:mm:ss.sssZ - Example:
2025-11-20T17:00:00.000Z
Resource Errors
NOT_FOUND
HTTP Status: 404
Description: The requested resource does not exist.
{
"error": {
"code": "NOT_FOUND",
"message": "Log message not found"
}
}
Resolution:
- Verify the resource ID is correct
- Check if the resource has been deleted
- Ensure you're querying the correct environment
RATE_LIMITED (Dashboard Level)
HTTP Status: 429
Description: Rate limit exceeded at the Dashboard/Auth Server level.
{
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests, please slow down"
}
}
Resolution:
- Implement exponential backoff
- Reduce request frequency
- Implement client-side caching
- Optimize API usage patterns (use pagination, avoid polling)
Note: Rate limiting is enforced by the Dashboard Auth Server, not Link Tracker service itself.
Server Errors
SERVICE_UNAVAILABLE
HTTP Status: 503
Description: Service temporarily unavailable.
{
"error": {
"code": "SERVICE_UNAVAILABLE",
"message": "Service is temporarily unavailable"
}
}
Resolution:
- Retry the request after a brief delay
- Contact support if the error persists, including the
requestId
INTERNAL_ERROR
HTTP Status: 500
Description: Unexpected server error.
{
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred"
}
}
Resolution:
- Retry the request after a brief delay
- Contact support if the error persists, including the
requestId
Error Handling Best Practices
1. Implement Proper Error Handling
Always handle errors gracefully in your application:
async function fetchLogMessages(url, options) {
try {
const response = await fetch(url, options);
const data = await response.json();
if (!response.ok) {
throw new APIError(data.error, response.status);
}
return data;
} catch (error) {
if (error instanceof APIError) {
handleAPIError(error);
} else {
handleNetworkError(error);
}
throw error;
}
}
class APIError extends Error {
constructor(errorData, statusCode) {
super(errorData.message);
this.code = errorData.code;
this.statusCode = statusCode;
this.details = errorData.details || [];
this.requestId = errorData.requestId;
}
}
2. Handle Different Error Types
Create specific handlers for different error categories:
function handleAPIError(error) {
switch (error.code) {
case 'INVALID_API_KEY':
case 'TOKEN_EXPIRED':
handleAuthenticationError(error);
break;
case 'RATE_LIMITED':
handleRateLimitError(error);
break;
case 'RESOURCE_NOT_FOUND':
handleNotFoundError(error);
break;
case 'VALIDATION_ERROR':
handleValidationError(error);
break;
default:
handleGenericError(error);
}
}
3. Implement Retry Logic
Use exponential backoff for retryable errors:
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fetch(url, options);
} catch (error) {
if (i === maxRetries - 1 || !isRetryable(error)) {
throw error;
}
const delay = Math.pow(2, i) * 1000; // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
function isRetryable(error) {
const retryableStatus = [408, 429, 500, 502, 503, 504];
return retryableStatus.includes(error.statusCode);
}
Error Recovery Strategies
Idempotency
Use idempotency keys to safely retry requests:
curl -X POST "https://api.ledgerlink.ai/v1/tracker/log-messages" \
-H "X-API-KEY: your_api_key" \
-H "X-Idempotency-Key: unique_key_here" \
-H "Content-Type: application/json" \
-d '{...}'
Circuit Breaker Pattern
Implement circuit breakers for resilience:
class CircuitBreaker {
constructor(threshold = 5, timeout = 60000) {
this.threshold = threshold;
this.timeout = timeout;
this.failures = 0;
this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
this.nextAttempt = Date.now();
}
async execute(fn) {
if (this.state === 'OPEN') {
if (Date.now() < this.nextAttempt) {
throw new Error('Circuit breaker is OPEN');
}
this.state = 'HALF_OPEN';
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
onSuccess() {
this.failures = 0;
this.state = 'CLOSED';
}
onFailure() {
this.failures++;
if (this.failures >= this.threshold) {
this.state = 'OPEN';
this.nextAttempt = Date.now() + this.timeout;
}
}
}
Monitoring and Alerting
Error Rate Monitoring
Track error rates and patterns:
class ErrorMonitor {
constructor() {
this.errorCounts = new Map();
this.errorRates = new Map();
}
recordError(errorCode, endpoint) {
const key = `${errorCode}:${endpoint}`;
const count = this.errorCounts.get(key) || 0;
this.errorCounts.set(key, count + 1);
}
calculateErrorRate(endpoint) {
const totalRequests = this.getTotalRequests(endpoint);
const errorRequests = this.getErrorRequests(endpoint);
return (errorRequests / totalRequests) * 100;
}
updateErrorRates(endpoint) {
const errorRate = this.calculateErrorRate(endpoint);
// Alert if error rate exceeds threshold
if (errorRate > 5) { // 5% error rate
this.sendAlert(endpoint, errorRate);
}
}
sendAlert(endpoint, errorRate) {
console.warn(`High error rate detected: ${endpoint} - ${errorRate.toFixed(2)}% `);
// Send to monitoring service
}
}
Health Checks
Implement health checks for proactive monitoring:
curl -X GET "https://api.ledgerlink.ai/v1/tracker/health" \
-H "X-API-KEY: your_api_key"
Response:
{
"status": "healthy",
"checks": {
"database": true,
"messageQueue": true,
"websocket": true
},
"timestamp": "2025-11-20T17:00:00.000Z"
}
Troubleshooting Common Issues
Issue: "Invalid API Key" Error
Symptoms: 401 status with INVALID_API_KEY error code
Causes:
- Incorrect API key
- API key revoked or expired
- Using sandbox key in production (or vice versa)
Solution:
- Verify API key is correct
- Check environment (sandbox vs production)
- Contact support to verify key status
Issue: Rate Limiting
Symptoms: 429 status with RATE_LIMITED error code
Causes:
- Too many requests in short time
- Inefficient API usage
- Missing request optimization
Solution:
- Implement exponential backoff
- Reduce request frequency
- Implement client-side caching
- Optimize API usage patterns (use pagination, avoid polling)
Issue: Timeout Errors
Symptoms: 504 status or network timeout
Causes:
- Large result sets
- Complex queries
- Network connectivity issues
Solution:
- Use pagination for large datasets
- Simplify query filters
- Implement proper timeout handling
- Check network connectivity
Getting Help
Support Channels
- Technical Support: Include error codes and request IDs
- Documentation: Refer to specific API documentation
- Status Page: Check for known issues
- Community Forum: Search for similar issues
Information to Include
When reporting errors, include:
- Error code and message
- Request ID (if available)
- HTTP status code
- Request payload (sanitized)
- Timestamp of occurrence
- Steps to reproduce
Proper error handling is crucial for building robust integrations with Link Tracker. Follow these guidelines to create resilient applications that gracefully handle edge cases and provide excellent user experiences.