The Solicitud Transporte API implements comprehensive error handling with standardized response formats, detailed validation messages in Spanish, and multiple layers of error interception.
All error messages are localized to Spanish to match the target user base in El Salvador.
{ "exito": false, "mensaje": "Error de validación en los datos enviados", "detalle": [ "El campo 'asunto' es obligatorio", "El campo 'cantidadPasajeros' debe ser mayor o igual al mínimo permitido" ]}
All Pydantic validation errors are intercepted and translated (main.py:70):
@app.exception_handler(RequestValidationError)async def validation_exception_handler(request: Request, exc: RequestValidationError): """Captures Pydantic validation errors and returns them in Spanish""" errores = [] for error in exc.errors(): campo = " → ".join(str(loc) for loc in error["loc"] if loc != "body") tipo = error["type"] msg_original = error["msg"] # Translate common messages mensaje = _traducir_error_validacion(campo, tipo, msg_original, error) errores.append(mensaje) return JSONResponse( status_code=422, content={ "exito": False, "mensaje": "Error de validación en los datos enviados", "detalle": errores } )
Common Pydantic errors are translated to Spanish (main.py:94):
Required Fields
Type Errors
Range Errors
Custom Validators
English:Field requiredSpanish:El campo '{campo}' es obligatorioExample:
{ "exito": false, "mensaje": "Error de validación en los datos enviados", "detalle": [ "El campo 'asunto' es obligatorio", "El campo 'cantidadPasajeros' es obligatorio" ]}
Translations:
int_parsing → El campo '{campo}' debe ser un número entero
string_type → El campo '{campo}' debe ser texto
bool_parsing → El campo '{campo}' debe ser verdadero o falso
date_parsing → El campo '{campo}' debe ser una fecha válida (YYYY-MM-DD)
Example:
{ "detalle": [ "El campo 'cantidadPasajeros' debe ser un número entero" ]}
Translations:
string_too_short → El campo '{campo}' es demasiado corto
string_too_long → El campo '{campo}' excede la longitud máxima permitida
greater_than_equal → El campo '{campo}' debe ser mayor o igual al mínimo permitido
less_than_equal → El campo '{campo}' debe ser menor o igual al máximo permitido
Models can define custom validators with Spanish messages:
@field_validator("codigo")@classmethoddef codigo_sin_espacios(cls, v: str) -> str: v = v.strip().upper() if not v: raise ValueError("El código no puede estar vacío") if " " in v: raise ValueError( "El código no debe contener espacios, " "use guion bajo (_) como separador" ) return v
def _validar_fk_existe(self, tabla: str, id_registro: int) -> bool: """Validates that a foreign key reference exists and is not deleted""" query = f"SELECT Id FROM {tabla} WHERE Id = %s AND Eliminado = 0" resultado = self.db.select(query, (id_registro,)) return bool(resultado)# Usageif not self._validar_fk_existe("Perfil", id_solicitante): return { "error": f"El perfil solicitante con Id {id_solicitante} no existe o está inactivo", "status": 400 }
Database configuration is validated on startup (sql_connection.py:47):
def _validar_configuracion(self): """Validates that all required configurations are present""" missing = [] if not self.server: missing.append("SQL_HOST") if not self.database: missing.append("SQL_NAME") if not self.username: missing.append("SQL_USER") if not self.password: missing.append("SQL_PASSWORD") if missing: raise EnvironmentError( f"Faltan configuraciones de SQL Server en .env: {', '.join(missing)}" )