Error Handling / Manejo de Errores
Learn how to handle errors gracefully in your LosCenotes API integration.
Aprende a manejar errores correctamente en tu integración con la API de LosCenotes.
Error Response Format / Formato de Respuesta de Error
All API errors follow a consistent structure:
Todos los errores de la API siguen una estructura consistente:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "One or more fields are invalid",
"status": 400,
"details": {
"field": "email",
"constraint": "Invalid email format"
},
"requestId": "req_1234567890abcdef",
"timestamp": "2024-01-15T10:30:00Z"
}
}
HTTP Status Codes / Códigos de Estado HTTP
The LosCenotes API uses standard HTTP status codes:
La API de LosCenotes usa códigos de estado HTTP estándar:
| Status Code | Meaning / Significado | Description / Descripción |
|---|---|---|
| 200 | OK | Request successful / Solicitud exitosa |
| 201 | Created / Creado | Resource created successfully / Recurso creado exitosamente |
| 400 | Bad Request / Solicitud Incorrecta | Invalid request parameters / Parámetros de solicitud inválidos |
| 401 | Unauthorized / No Autorizado | Invalid or missing API key / Llave API inválida o faltante |
| 403 | Forbidden / Prohibido | Insufficient permissions / Permisos insuficientes |
| 404 | Not Found / No Encontrado | Resource not found / Recurso no encontrado |
| 409 | Conflict / Conflicto | Resource already exists / El recurso ya existe |
| 422 | Unprocessable Entity | Validation failed / Validación fallida |
| 429 | Too Many Requests | Rate limit exceeded / Límite de tasa excedido |
| 500 | Internal Server Error | Server error / Error del servidor |
| 503 | Service Unavailable | Service temporarily unavailable / Servicio temporalmente no disponible |
Common Error Codes / Códigos de Error Comunes
Authentication Errors / Errores de Autenticación
INVALID_API_KEY
{
"success": false,
"error": {
"code": "INVALID_API_KEY",
"message": "The provided API key is invalid",
"status": 401
}
}
AUTHENTICATION_REQUIRED
{
"success": false,
"error": {
"code": "AUTHENTICATION_REQUIRED",
"message": "Authentication is required for this endpoint",
"status": 401
}
}
Validation Errors / Errores de Validación
VALIDATION_ERROR
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "One or more fields are invalid",
"status": 400,
"details": [
{
"field": "email",
"constraint": "Invalid email format"
}
]
}
}
Resource Errors / Errores de Recurso
RESOURCE_NOT_FOUND
{
"success": false,
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "The requested resource was not found",
"status": 404,
"details": {
"resource": "cenote",
"id": "cenote-not-found"
}
}
}
Business Logic Errors / Errores de Lógica de Negocio
CENOTE_NOT_AVAILABLE
{
"success": false,
"error": {
"code": "CENOTE_NOT_AVAILABLE",
"message": "The cenote is not available for the selected date",
"status": 422,
"details": {
"cenoteId": "cenote-uuid",
"date": "2025-01-15",
"reason": "maintenance"
}
}
}
INSUFFICIENT_CAPACITY
{
"success": false,
"error": {
"code": "INSUFFICIENT_CAPACITY",
"message": "Not enough capacity for the requested reservation",
"status": 422,
"details": {
"requested": 10,
"available": 5
}
}
}
Rate Limiting Errors / Errores de Límite de Tasa
RATE_LIMIT_EXCEEDED
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please try again later",
"status": 429,
"details": {
"limit": 1000,
"window": "1 hour",
"resetTime": "2025-01-15T11:00:00Z"
}
}
}
Error Handling Best Practices / Mejores Prácticas
1. Always Check the Success Field / Siempre Verifica el Campo Success
const response = await fetch('https://service-gateway.loscenotes.com/partner/cenotes', {
headers: { 'X-API-Key': apiKey }
});
const data = await response.json();
if (!data.success) {
console.error('API Error:', data.error.code, data.error.message);
// Handle specific error codes
switch (data.error.code) {
case 'RESOURCE_NOT_FOUND':
// Handle not found
break;
case 'RATE_LIMIT_EXCEEDED':
// Implement backoff strategy
break;
default:
// Handle generic error
break;
}
return;
}
// Success - use data.data
console.log(data.data);
2. Implement Exponential Backoff / Implementa Backoff Exponencial
async function apiCallWithRetry(apiCall, maxRetries = 3, baseDelay = 1000) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await apiCall();
const data = await response.json();
if (data.success) {
return data;
}
if (data.error.status === 429 && attempt < maxRetries - 1) {
const delay = baseDelay * Math.pow(2, attempt);
console.log(`Rate limited. Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw data.error;
} catch (error) {
if (attempt === maxRetries - 1) throw error;
}
}
throw new Error('Max retries exceeded');
}
// Usage / Uso
const data = await apiCallWithRetry(() =>
fetch('https://service-gateway.loscenotes.com/partner/cenotes', {
headers: { 'X-API-Key': apiKey }
})
);
3. Validate Input Before API Calls / Valida Entrada Antes de Llamadas API
function validateReservationData(data) {
const errors = [];
if (!data.cenoteId) {
errors.push('Cenote ID is required');
}
if (!data.date || new Date(data.date) < new Date()) {
errors.push('Valid future date is required');
}
if (!data.ageBreakdown || !data.ageBreakdown.adult) {
errors.push('At least one adult is required');
}
return errors;
}
// Usage / Uso
const validationErrors = validateReservationData(reservationData);
if (validationErrors.length > 0) {
console.error('Validation errors:', validationErrors);
return;
}
// Proceed with API call
const response = await createReservation(reservationData);
4. Handle Network Errors / Maneja Errores de Red
try {
const response = await fetch('https://service-gateway.loscenotes.com/partner/cenotes', {
headers: { 'X-API-Key': apiKey }
});
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
const data = await response.json();
// Process data...
} catch (error) {
if (error.name === 'TypeError') {
console.error('Network error - check your internet connection');
} else if (error.message.includes('timeout')) {
console.error('Request timeout - try again later');
} else {
console.error('Error:', error.message);
}
}
5. Log Errors for Debugging / Registra Errores para Depuración
function logApiError(error, context) {
const errorLog = {
timestamp: new Date().toISOString(),
requestId: error.requestId,
endpoint: context.endpoint,
method: context.method,
errorCode: error.code || 'UNKNOWN_ERROR',
errorMessage: error.message || 'Unknown error occurred',
details: error.details
};
console.error('LosCenotes API Error:', JSON.stringify(errorLog, null, 2));
// Send to your logging service
// yourLogger.error(errorLog);
}
// Usage / Uso
try {
const response = await makeApiCall();
} catch (error) {
logApiError(error, {
endpoint: '/partner/cenotes',
method: 'GET'
});
}
Pricing Specific Errors / Errores Específicos de Precios
| Code / Código | Description / Descripción |
|---|---|
error.cenote.not_found | Cenote ID not found / ID de cenote no encontrado |
error.tour.not_found | Tour ID not found / ID de tour no encontrado |
error.pricing.invalid_item_type | Item type must be "cenote" or "tour" / Tipo de item debe ser "cenote" o "tour" |
error.transport.pickup_required_when_included | Pickup info required when transport is included / Info de recogida requerida |
Payment Errors / Errores de Pago
| Code / Código | Description / Descripción |
|---|---|
card_declined | Card was declined / Tarjeta rechazada |
insufficient_funds | Insufficient funds / Fondos insuficientes |
expired_card | Card has expired / Tarjeta expirada |
invalid_cvc | Invalid security code / Código de seguridad inválido |
processing_error | Payment processing error / Error de procesamiento |