Error Response Format
All API endpoints return consistent error responses with the following structure:{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
"field": "specific_field_name",
"value": "invalid_value"
}
}
}
Common Error Codes
Authentication Errors
Invalid API Key
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}
try {
const response = await api.getLocations();
} catch (error) {
if (error.response?.status === 401) {
console.error('Invalid API key. Please check your credentials.');
// Redirect to login or show authentication error
}
}
try:
response = api.get_locations()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
print("Invalid API key. Please check your credentials.")
# Handle authentication error
Missing API Key
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "API key is required"
}
}
# ❌ Missing API key
curl -X GET "https://apistg.arqq.in/api/locations"
# ✅ Correct with API key
curl -X GET "https://apistg.arqq.in/api/locations" \
-H "X-API-Key: YOUR_API_KEY"
Validation Errors
Invalid Plate Format
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid plate number format",
"details": {
"field": "plateNumber",
"value": "INVALID_PLATE"
}
}
}
function validatePlateData(plateData) {
const { plateType, plateCode, plateNumber } = plateData;
const errors = [];
// Validate plate type
if (!/^[A-Z]{2,4}$/.test(plateType)) {
errors.push('Plate type must be 2-4 uppercase letters (e.g., DXB, AUH)');
}
// Validate plate code
if (!/^(White|[A-Za-z0-9]{1,3})$/.test(plateCode)) {
errors.push('Plate code must be "White" or 1-3 alphanumeric characters');
}
// Validate plate number
if (!/^\d+$/.test(plateNumber)) {
errors.push('Plate number must contain only digits');
}
return errors;
}
// Usage
const plateData = {
plateType: "DXB",
plateCode: "White",
plateNumber: "12345"
};
const errors = validatePlateData(plateData);
if (errors.length > 0) {
console.error('Validation errors:', errors);
} else {
// Proceed with API call
}
import re
def validate_plate_data(plate_data):
errors = []
plate_type = plate_data.get('plateType', '')
plate_code = plate_data.get('plateCode', '')
plate_number = plate_data.get('plateNumber', '')
# Validate plate type
if not re.match(r'^[A-Z]{2,4}$', plate_type):
errors.append('Plate type must be 2-4 uppercase letters (e.g., DXB, AUH)')
# Validate plate code
if not re.match(r'^(White|[A-Za-z0-9]{1,3})$', plate_code):
errors.append('Plate code must be "White" or 1-3 alphanumeric characters')
# Validate plate number
if not re.match(r'^\d+$', plate_number):
errors.append('Plate number must contain only digits')
return errors
# Usage
plate_data = {
'plateType': 'DXB',
'plateCode': 'White',
'plateNumber': '12345'
}
errors = validate_plate_data(plate_data)
if errors:
print('Validation errors:', errors)
else:
# Proceed with API call
pass
Missing Required Fields
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Missing required field: referenceId",
"details": {
"field": "referenceId",
"value": null
}
}
}
// ❌ Missing required field
const vehicleData = {
plateType: "DXB",
plateCode: "White",
plateNumber: "12345"
// Missing referenceId
};
// ✅ Complete data
const vehicleData = {
referenceId: "RESIDENT_001", // Required field
plateType: "DXB",
plateCode: "White",
plateNumber: "12345",
vehicleType: "Sedan",
note: "Primary vehicle"
};
Resource Not Found Errors
Invalid Location ID
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Location not found",
"details": {
"field": "locationId",
"value": "invalid_location_123"
}
}
}
async function getLocationSafely(locationId) {
try {
const response = await api.getLocation(locationId);
return response.data;
} catch (error) {
if (error.response?.status === 404) {
console.error(`Location ${locationId} not found`);
return null;
}
throw error;
}
}
Location Update Errors
When updating locations, you may encounter specific errors:{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Location not found or not accessible",
"details": {
"field": "locationId",
"value": "invalid_location_123"
}
}
}
{
"success": false,
"error": {
"code": "CONFLICT",
"message": "Location slug already exists in this company"
}
}
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Slug must contain only lowercase letters, numbers, and hyphens"
}
}
async function updateLocationSafely(locationId, updateData) {
try {
const response = await api.updateLocation(locationId, updateData);
return response.data;
} catch (error) {
if (error.response?.status === 404) {
const errorData = error.response.data;
if (errorData.error?.code === 'NOT_FOUND') {
console.error(`Location ${locationId} not found`);
return null;
}
} else if (error.response?.status === 409) {
const errorData = error.response.data;
if (errorData.error?.code === 'CONFLICT') {
console.error('Location slug already exists in this company');
return { error: 'slug_conflict' };
}
} else if (error.response?.status === 400) {
const errorData = error.response.data;
if (errorData.error?.code === 'VALIDATION_ERROR') {
console.error('Validation error:', errorData.error.message);
return { error: 'validation', message: errorData.error.message };
}
}
throw error;
}
}
def update_location_safely(api, location_id, update_data):
try:
response = api.update_location(location_id, update_data)
return response
except requests.exceptions.HTTPError as e:
if e.response.status_code == 404:
error_data = e.response.json()
if error_data.get('error', {}).get('code') == 'NOT_FOUND':
print(f"Location {location_id} not found")
return None
elif e.response.status_code == 409:
error_data = e.response.json()
if error_data.get('error', {}).get('code') == 'CONFLICT':
print("Location slug already exists in this company")
return {'error': 'slug_conflict'}
elif e.response.status_code == 400:
error_data = e.response.json()
if error_data.get('error', {}).get('code') == 'VALIDATION_ERROR':
print("Validation error:", error_data['error']['message'])
return {'error': 'validation', 'message': error_data['error']['message']}
raise
Invalid Whitelist ID
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Whitelist entry not found",
"details": {
"field": "whitelistId",
"value": "invalid_whitelist_123"
}
}
}
Duplicate Vehicle Errors
{
"success": false,
"error": {
"code": "DUPLICATE_VEHICLE",
"message": "Vehicle with this plate already exists in whitelist",
"details": {
"plateType": "DXB",
"plateCode": "White",
"plateNumber": "12345"
}
}
}
async function addVehicleSafely(locationId, vehicleData) {
try {
return await api.addWhitelistVehicle(locationId, vehicleData);
} catch (error) {
if (error.response?.status === 409) {
const errorData = error.response.data;
console.log('Vehicle already exists:', errorData.error.details);
// Option 1: Return existing vehicle info
return { success: false, reason: 'duplicate', details: errorData.error.details };
// Option 2: Update existing vehicle instead
// const existingVehicle = await findExistingVehicle(locationId, vehicleData);
// return await api.updateWhitelistVehicle(locationId, existingVehicle.id, vehicleData);
}
throw error;
}
}
Rate Limiting Errors
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests"
}
}
class RateLimitHandler {
constructor() {
this.retryDelay = 1000; // Start with 1 second
this.maxRetries = 3;
}
async makeRequestWithRetry(requestFn) {
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
try {
return await requestFn();
} catch (error) {
if (error.response?.status === 429) {
const retryAfter = error.response.headers['retry-after'] || this.retryDelay;
console.log(`Rate limit exceeded. Retrying in ${retryAfter} seconds...`);
if (attempt < this.maxRetries - 1) {
await this.sleep(retryAfter * 1000);
this.retryDelay *= 2; // Exponential backoff
continue;
}
}
throw error;
}
}
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Usage
const rateLimitHandler = new RateLimitHandler();
try {
const result = await rateLimitHandler.makeRequestWithRetry(
() => api.addWhitelistVehicle(locationId, vehicleData)
);
} catch (error) {
console.error('Request failed after retries:', error.message);
}
Network Errors
Connection Timeout
async function makeRequestWithTimeout(url, options, timeout = 10000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
...options,
signal: controller.signal
});
clearTimeout(timeoutId);
return response;
} catch (error) {
clearTimeout(timeoutId);
if (error.name === 'AbortError') {
throw new Error('Request timeout - please check your connection');
}
throw error;
}
}
import requests
from requests.exceptions import Timeout, ConnectionError
def make_request_with_retry(url, headers, data=None, timeout=10, max_retries=3):
for attempt in range(max_retries):
try:
if data:
response = requests.post(url, headers=headers, json=data, timeout=timeout)
else:
response = requests.get(url, headers=headers, timeout=timeout)
response.raise_for_status()
return response
except Timeout:
print(f"Request timeout (attempt {attempt + 1}/{max_retries})")
if attempt < max_retries - 1:
time.sleep(2 ** attempt) # Exponential backoff
continue
raise Exception("Request timeout after all retries")
except ConnectionError:
print(f"Connection error (attempt {attempt + 1}/{max_retries})")
if attempt < max_retries - 1:
time.sleep(2 ** attempt)
continue
raise Exception("Connection error after all retries")
Comprehensive Error Handler
Complete Error Handler Implementation
Complete Error Handler Implementation
Implement a comprehensive error handler for all scenarios:
class APIErrorHandler {
static handleError(error, context = {}) {
const errorInfo = {
timestamp: new Date().toISOString(),
context,
...this.parseError(error)
};
// Log error for debugging
console.error('API Error:', errorInfo);
// Return user-friendly error message
return {
success: false,
error: errorInfo,
userMessage: this.getUserMessage(errorInfo)
};
}
static parseError(error) {
if (error.response) {
const { status, data } = error.response;
return {
type: 'api_error',
status,
code: data?.error?.code || 'UNKNOWN_ERROR',
message: data?.error?.message || 'API request failed',
details: data?.error?.details
};
} else if (error.request) {
return {
type: 'network_error',
message: 'Unable to connect to API server'
};
} else {
return {
type: 'client_error',
message: error.message || 'An unexpected error occurred'
};
}
}
static getUserMessage(errorInfo) {
switch (errorInfo.code) {
case 'UNAUTHORIZED':
return 'Please check your API key and try again.';
case 'FORBIDDEN':
return 'You do not have permission to access this resource.';
case 'NOT_FOUND':
return 'The requested resource was not found.';
case 'VALIDATION_ERROR':
return 'Please check your input data and try again.';
case 'DUPLICATE_VEHICLE':
return 'This vehicle is already in the whitelist.';
case 'RATE_LIMIT_EXCEEDED':
return 'Too many requests. Please wait a moment and try again.';
default:
return 'An error occurred. Please try again later.';
}
}
}
// Usage
try {
const result = await api.addWhitelistVehicle(locationId, vehicleData);
} catch (error) {
const errorInfo = APIErrorHandler.handleError(error, {
operation: 'add_vehicle',
locationId,
vehicleData
});
// Show user-friendly message
showNotification(errorInfo.userMessage);
// Log detailed error for debugging
console.error('Detailed error:', errorInfo);
}
Troubleshooting Checklist
1
Check API Key
Verify your API key is correct and has the necessary permissions for the requested resource.
2
Validate Request Data
Ensure all required fields are present and data formats are correct according to the API specification.
3
Check Rate Limits
Verify you haven’t exceeded the 1000 requests per hour limit. Check rate limit headers in responses.
4
Verify Resource IDs
Confirm that location IDs and whitelist IDs are valid and exist in your account.
5
Test Network Connectivity
Ensure your application can reach the API endpoints and there are no firewall or network issues.
Getting Help
Contact Support
Get help with specific error scenarios and troubleshooting.
API Status
Check API status and known issues.

