Por Que Importa el Testing de Manejo de Errores
Cuando una API funciona perfectamente, el testing es sencillo. El verdadero desafio — y donde se esconden la mayoria de los bugs — esta en como la API maneja cuando las cosas salen mal. El testing de manejo de errores verifica que la API falle graciosamente, proporcione informacion util y no exponga vulnerabilidades.
En produccion en companias como Google, la calidad del manejo de errores impacta directamente la velocidad de debugging. Un mensaje de error claro como “El campo ’email’ debe ser una direccion de email valida” ahorra horas comparado con un generico “Bad Request.”
Estructura de Respuesta de Error
Una respuesta de error bien disenada sigue un formato consistente:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "La validacion del request fallo",
"details": [
{
"field": "email",
"message": "Debe ser una direccion de email valida",
"value": "no-es-email"
},
{
"field": "age",
"message": "Debe ser un entero positivo",
"value": -5
}
]
},
"requestId": "req_abc123",
"timestamp": "2025-12-15T10:30:00Z"
}
Que Testear en Respuestas de Error
| Aspecto | Que Verificar |
|---|---|
| Status code | Coincide con el tipo de error (400, 401, 403, 404, 422, 500) |
| Codigo de error | Legible por maquina, consistente en toda la API |
| Mensaje | Legible por humanos, accionable, sin detalles internos |
| Detalles | Errores especificos por campo cuando aplique |
| ID de request | Presente para debugging y tickets de soporte |
| Content-Type | Sigue siendo application/json incluso para errores |
Categorias de Testing de Errores
Errores de Validacion de Input (400/422)
Testea cada campo de input con datos invalidos:
Campos requeridos faltantes → "El campo 'name' es requerido"
Tipo de dato incorrecto → "El campo 'age' debe ser un entero"
Fuera de rango → "El campo 'age' debe estar entre 0 y 150"
Formato invalido → "El campo 'email' debe ser un email valido"
Demasiado largo → "El campo 'name' maximo 100 caracteres"
Enum invalido → "El campo 'role' debe ser: admin, user, viewer"
Errores de Autenticacion (401)
| Escenario | Mensaje Esperado |
|---|---|
| Sin token | “Autenticacion requerida” |
| Token expirado | “El token ha expirado” |
| Token malformado | “Token de autenticacion invalido” |
| Token revocado | “El token ha sido revocado” |
Errores de Autorizacion (403)
| Escenario | Mensaje Esperado |
|---|---|
| Usuario en endpoint admin | “Permisos insuficientes” |
| Datos de otro usuario | “Acceso denegado” |
| Feature deshabilitado | “No disponible para tu plan” |
Errores Not Found (404)
| Escenario | Mensaje Esperado |
|---|---|
| ID invalido | “Usuario no encontrado” |
| Recurso eliminado | “El recurso ya no existe” |
| Endpoint incorrecto | Respuesta 404 estandar |
Testing Avanzado de Errores
Consistencia de Errores
Verifica que los errores siguen el mismo formato en toda la API:
- Misma estructura JSON para todas las respuestas de error
- Codigos de error consistentes
- Uso consistente de status codes
Seguridad en Mensajes de Error
Testea que los mensajes de error NO revelen:
- Nombres de tablas o columnas de base de datos
- Stack traces o rutas de archivos
- Consultas SQL u operaciones NoSQL
- Nombres de servicios internos o direcciones IP
- Si un username existe (para endpoints de login)
Malo: "Error: SELECT * FROM users WHERE id=42 failed: connection to postgres:5432 refused"
Bueno: "No se pudo procesar el request. Intenta mas tarde. Referencia: req_abc123"
Manejo de Errores Bajo Estres
- Que pasa cuando la base de datos esta caida? (503, no 500 con stack trace)
- Que pasa con JSON malformado? (400, no 500)
- Que pasa con payloads extremadamente grandes? (413 Payload Too Large)
- Que pasa con Content-Type no soportado? (415)
Mensajes de Error Internacionalizados
Si la API soporta multiples idiomas, testea:
- Mensajes en cada idioma via Accept-Language
- Fallback al idioma por defecto
- Codigos de error iguales sin importar el idioma
Construyendo un Suite de Tests de Error
Para cada endpoint, crea una matriz sistematica:
POST /api/users
├── 'name' faltante → 400, VALIDATION_ERROR
├── 'name' vacio → 400, VALIDATION_ERROR
├── Nombre muy largo → 400, VALIDATION_ERROR
├── Email invalido → 422, VALIDATION_ERROR
├── Email duplicado → 409, CONFLICT
├── Sin token auth → 401, AUTH_REQUIRED
├── Token invalido → 401, INVALID_TOKEN
├── Rol usuario en admin → 403, FORBIDDEN
├── JSON malformado → 400, PARSE_ERROR
└── Content-Type erroneo → 415, UNSUPPORTED_MEDIA_TYPE
Ejercicio Practico
- Mapea respuestas de error: Envia 10 requests invalidos a JSONPlaceholder y documenta cada formato de respuesta
- Verifica consistencia: Compara formatos de error entre endpoints
- Auditoria de seguridad: Busca respuestas que revelen detalles internos
- Crea una matriz de error: Para un endpoint de registro, lista todos los escenarios de error posibles
Puntos Clave
- El testing de errores es tan importante como el happy path — aqui se esconden vulnerabilidades y mala experiencia de usuario
- Las respuestas de error deben seguir estructura consistente: status code, codigo de error, mensaje legible y detalles por campo
- Nunca expongas detalles internos en mensajes de error — es un riesgo de seguridad
- Testea cada campo con cada tipo de dato invalido: faltante, vacio, tipo incorrecto, fuera de rango, muy largo, formato invalido
- Construye matrices de test de error sistematicas para cada endpoint