Skip to main content

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 CodeMeaning / SignificadoDescription / Descripción
200OKRequest successful / Solicitud exitosa
201Created / CreadoResource created successfully / Recurso creado exitosamente
400Bad Request / Solicitud IncorrectaInvalid request parameters / Parámetros de solicitud inválidos
401Unauthorized / No AutorizadoInvalid or missing API key / Llave API inválida o faltante
403Forbidden / ProhibidoInsufficient permissions / Permisos insuficientes
404Not Found / No EncontradoResource not found / Recurso no encontrado
409Conflict / ConflictoResource already exists / El recurso ya existe
422Unprocessable EntityValidation failed / Validación fallida
429Too Many RequestsRate limit exceeded / Límite de tasa excedido
500Internal Server ErrorServer error / Error del servidor
503Service UnavailableService 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ódigoDescription / Descripción
error.cenote.not_foundCenote ID not found / ID de cenote no encontrado
error.tour.not_foundTour ID not found / ID de tour no encontrado
error.pricing.invalid_item_typeItem type must be "cenote" or "tour" / Tipo de item debe ser "cenote" o "tour"
error.transport.pickup_required_when_includedPickup info required when transport is included / Info de recogida requerida

Payment Errors / Errores de Pago

Code / CódigoDescription / Descripción
card_declinedCard was declined / Tarjeta rechazada
insufficient_fundsInsufficient funds / Fondos insuficientes
expired_cardCard has expired / Tarjeta expirada
invalid_cvcInvalid security code / Código de seguridad inválido
processing_errorPayment processing error / Error de procesamiento

Next Steps / Siguientes Pasos