372 lines
8.9 KiB
Markdown
372 lines
8.9 KiB
Markdown
# Manejo de Errores
|
||
|
||
## Clasificación de Errores
|
||
|
||
DataTransferV2 clasifica los errores en tres categorías principales con diferentes impactos en el pipeline.
|
||
|
||
## Estados de Ejecución
|
||
|
||
### SUCCESS (✅)
|
||
**Definición:** Ejecución completamente exitosa
|
||
**Condiciones:**
|
||
- Datos encontrados en base de datos
|
||
- Archivo Excel generado correctamente
|
||
- Todos los destinos de distribución exitosos
|
||
|
||
**Ejemplo:**
|
||
```
|
||
✅ Cobertura-2024-01-15: 1,500 registros procesados, FTP+SharePoint OK
|
||
```
|
||
|
||
### COMPLETED_WITH_ERRORS (⚠️)
|
||
**Definición:** Datos procesados pero con fallos en distribución
|
||
**Condiciones:**
|
||
- Datos encontrados y Excel generado
|
||
- Al menos un destino de distribución falló
|
||
- Otros destinos pueden haber sido exitosos
|
||
|
||
**Impacto:** No detiene el pipeline, continúa con siguientes reportes
|
||
|
||
**Ejemplo:**
|
||
```
|
||
⚠️ Checkout-2024-01-15: Datos OK, FTP falló (timeout), SharePoint OK
|
||
```
|
||
|
||
### WARNING (ℹ️)
|
||
**Definición:** Sin datos disponibles
|
||
**Condiciones:**
|
||
- Query ejecutada correctamente
|
||
- 0 registros retornados
|
||
- No se genera archivo Excel
|
||
|
||
**Reglas de negocio:**
|
||
- Si es domingo + sin datos → Ignorado
|
||
- 3+ warnings consecutivos → Se eleva a FAILED
|
||
|
||
**Ejemplo:**
|
||
```
|
||
ℹ️ Promociones-2024-01-15: Sin datos disponibles
|
||
```
|
||
|
||
### FAILED (❌)
|
||
**Definición:** Fallo crítico que detiene el procesamiento
|
||
**Condiciones:**
|
||
- Error en conexión a base de datos
|
||
- Error en query SQL
|
||
- Error en generación de Excel
|
||
- 3+ warnings consecutivos en mismo reporte
|
||
|
||
**Impacto:** Detiene procesamiento del reporte actual
|
||
|
||
**Ejemplo:**
|
||
```
|
||
❌ QualityDisplay-2024-01-15: Error de conexión DB - timeout
|
||
```
|
||
|
||
## Tipos de Errores Técnicos
|
||
|
||
### Errores de Base de Datos
|
||
|
||
#### Connection Timeout
|
||
```
|
||
Error: [08001] [Microsoft][ODBC SQL Server Driver]Timeout expired
|
||
Causa: Red lenta, servidor sobrecargado
|
||
Solución: Reintentar, verificar conectividad
|
||
```
|
||
|
||
#### Authentication Failed
|
||
```
|
||
Error: [28000] [Microsoft][ODBC SQL Server Driver]Login failed
|
||
Causa: Credenciales incorrectas
|
||
Solución: Verificar USERNAME/PASSWORD en config
|
||
```
|
||
|
||
#### Database Not Found
|
||
```
|
||
Error: [08004] [Microsoft][ODBC SQL Server Driver]Server does not exist
|
||
Causa: Servidor incorrecto o no accesible
|
||
Solución: Verificar SERVER en config
|
||
```
|
||
|
||
#### Query Syntax Error
|
||
```
|
||
Error: [42000] [Microsoft][ODBC SQL Server Driver]Incorrect syntax
|
||
Causa: Nombre de tabla/columna incorrecto
|
||
Solución: Verificar configuración de reportes
|
||
```
|
||
|
||
### Errores de FTP
|
||
|
||
#### Connection Failed
|
||
```
|
||
Error: [Errno 110] Connection timed out
|
||
Causa: Firewall, red bloqueada
|
||
Solución: Verificar host/puerto, permisos de red
|
||
```
|
||
|
||
#### Authentication Failed
|
||
```
|
||
Error: 530 Login incorrect
|
||
Causa: Credenciales FTP incorrectas
|
||
Solución: Verificar FTP_CONFIG
|
||
```
|
||
|
||
#### Permission Denied
|
||
```
|
||
Error: 550 Permission denied
|
||
Causa: Usuario sin permisos de escritura
|
||
Solución: Verificar permisos en servidor FTP
|
||
```
|
||
|
||
#### Disk Full
|
||
```
|
||
Error: 452 Insufficient storage space
|
||
Causa: Espacio insuficiente en servidor
|
||
Solución: Liberar espacio, contactar administrador
|
||
```
|
||
|
||
### Errores de SFTP
|
||
|
||
#### SSH Connection Failed
|
||
```
|
||
Error: [Errno 61] Connection refused
|
||
Causa: Puerto cerrado, servidor no responde
|
||
Solución: Verificar host/puerto SFTP
|
||
```
|
||
|
||
#### Host Key Verification
|
||
```
|
||
Error: Host key verification failed
|
||
Causa: Primera conexión, clave host no conocida
|
||
Solución: Agregar host a known_hosts o usar policy
|
||
```
|
||
|
||
#### File Transfer Error
|
||
```
|
||
Error: Permission denied (publickey,password)
|
||
Causa: Autenticación fallida
|
||
Solución: Verificar credenciales SFTP
|
||
```
|
||
|
||
### Errores de SharePoint
|
||
|
||
#### Authentication Failed
|
||
```
|
||
Error: Invalid client credentials
|
||
Causa: client_id/tenant_id incorrectos
|
||
Solución: Verificar configuración Azure AD
|
||
```
|
||
|
||
#### Permission Denied
|
||
```
|
||
Error: Access denied
|
||
Causa: Usuario sin permisos en site/library
|
||
Solución: Verificar permisos en SharePoint
|
||
```
|
||
|
||
#### File Upload Failed
|
||
```
|
||
Error: The file exists
|
||
Causa: Archivo ya existe, no se puede sobrescribir
|
||
Solución: Verificar configuración de sobrescritura
|
||
```
|
||
|
||
### Errores de Sistema
|
||
|
||
#### Disk Full
|
||
```
|
||
Error: [Errno 28] No space left on device
|
||
Causa: Disco local lleno
|
||
Solución: Liberar espacio, verificar partición
|
||
```
|
||
|
||
#### Memory Error
|
||
```
|
||
Error: MemoryError
|
||
Causa: DataFrame muy grande
|
||
Solución: Optimizar query, procesar en lotes
|
||
```
|
||
|
||
#### Encoding Error
|
||
```
|
||
Error: 'utf-8' codec can't decode byte
|
||
Causa: Datos con caracteres especiales
|
||
Solución: Especificar encoding correcto
|
||
```
|
||
|
||
## Estrategias de Recuperación
|
||
|
||
### Reintentos Automáticos
|
||
|
||
```python
|
||
def retry_operation(operation, max_retries=3, delay=5):
|
||
for attempt in range(max_retries):
|
||
try:
|
||
return operation()
|
||
except Exception as e:
|
||
if attempt < max_retries - 1:
|
||
time.sleep(delay * (attempt + 1)) # Backoff exponencial
|
||
else:
|
||
raise e
|
||
```
|
||
|
||
**Aplicado a:**
|
||
- Conexiones de red (FTP, SFTP, SharePoint)
|
||
- Queries de base de datos
|
||
- Uploads de archivos
|
||
|
||
### Fallback Strategies
|
||
|
||
1. **Múltiples Destinos:** Si FTP falla, intentar SFTP
|
||
2. **Modo Degradado:** Continuar sin notificaciones si webhook falla
|
||
3. **Cache Local:** Guardar archivos localmente si uploads fallan
|
||
|
||
### Circuit Breaker
|
||
|
||
```python
|
||
class CircuitBreaker:
|
||
def __init__(self, failure_threshold=5, recovery_timeout=300):
|
||
self.failure_count = 0
|
||
self.last_failure_time = None
|
||
self.state = 'CLOSED' # CLOSED, OPEN, HALF_OPEN
|
||
|
||
def call(self, func):
|
||
if self.state == 'OPEN':
|
||
if time.time() - self.last_failure_time > self.recovery_timeout:
|
||
self.state = 'HALF_OPEN'
|
||
else:
|
||
raise CircuitBreakerError("Circuit is OPEN")
|
||
|
||
try:
|
||
result = func()
|
||
self._on_success()
|
||
return result
|
||
except Exception as e:
|
||
self._on_failure()
|
||
raise e
|
||
```
|
||
|
||
## Logging y Monitoreo
|
||
|
||
### Niveles de Log
|
||
|
||
- **DEBUG:** Detalles técnicos, queries ejecutadas
|
||
- **INFO:** Progreso normal, estadísticas
|
||
- **WARNING:** Situaciones no críticas
|
||
- **ERROR:** Errores que requieren atención
|
||
- **CRITICAL:** Errores que detienen el sistema
|
||
|
||
### Formato de Logs
|
||
|
||
```
|
||
2024-01-15 08:30:15,123 - ETL - INFO - Starting ETL for PG project
|
||
2024-01-15 08:30:16,456 - DB - DEBUG - Executing query: SELECT * FROM Cobertura WHERE Fecha = '2024-01-15'
|
||
2024-01-15 08:30:18,789 - REPORT - INFO - Generated Excel: Reportes/PG/Cobertura/Cobertura-20240115.xlsx
|
||
2024-01-15 08:30:20,012 - FTP - ERROR - Upload failed: Connection timeout
|
||
2024-01-15 08:30:25,345 - FTP - INFO - Retry 1/3 successful
|
||
```
|
||
|
||
### Base de Datos de Auditoría
|
||
|
||
Cada error se registra en `ExecutionLog`:
|
||
|
||
```sql
|
||
INSERT INTO ExecutionLog (
|
||
ProcedureID, StartTime, EndTime, Status,
|
||
ErrorType, ErrorMessage, RetryCount
|
||
) VALUES (
|
||
1001, '2024-01-15 08:30:15', '2024-01-15 08:30:25', 'COMPLETED_WITH_ERRORS',
|
||
'FTP_TIMEOUT', 'Connection timed out after 30s', 1
|
||
)
|
||
```
|
||
|
||
## Alertas y Notificaciones
|
||
|
||
### Umbrales de Alerta
|
||
|
||
- **Error Rate > 10%:** Notificación inmediata
|
||
- **3+ fallos consecutivos:** Alerta crítica
|
||
- **Tiempo de ejecución > 2x promedio:** Warning
|
||
- **Disco > 90% usado:** Alerta de capacidad
|
||
|
||
### Canales de Notificación
|
||
|
||
1. **WhatsApp:** Resúmenes diarios
|
||
2. **Email:** Alertas críticas
|
||
3. **Logs:** Registro detallado
|
||
4. **Dashboard:** Métricas en tiempo real (futuro)
|
||
|
||
## Debugging
|
||
|
||
### Herramientas de Diagnóstico
|
||
|
||
#### Verificar Conectividad
|
||
|
||
```bash
|
||
# Base de datos
|
||
sqlcmd -S sql.glmanalytics.com -U $USERNAME -P $PASSWORD -Q "SELECT 1"
|
||
|
||
# FTP
|
||
ftp $FTP_HOST
|
||
|
||
# SFTP
|
||
sftp $SFTP_USER@$SFTP_HOST
|
||
```
|
||
|
||
#### Analizar Logs
|
||
|
||
```bash
|
||
# Últimos errores
|
||
tail -f Logs/etl.log | grep ERROR
|
||
|
||
# Errores por tipo
|
||
grep "ERROR" Logs/etl.log | cut -d' ' -f4 | sort | uniq -c
|
||
```
|
||
|
||
#### Probar Componentes Individualmente
|
||
|
||
```python
|
||
# Probar DB
|
||
from App.Utils.db_utils import DatabaseManager
|
||
db = DatabaseManager()
|
||
data = db.execute_query("SELECT TOP 1 * FROM Cobertura")
|
||
|
||
# Probar FTP
|
||
from App.Utils.ftp_utils import FTPManager
|
||
ftp = FTPManager()
|
||
ftp.test_connection()
|
||
```
|
||
|
||
### Checklist de Troubleshooting
|
||
|
||
- [ ] Credenciales correctas en config
|
||
- [ ] Servidores accesibles (ping, telnet)
|
||
- [ ] Puertos abiertos (1433 DB, 21 FTP, 22 SFTP, 443 HTTPS)
|
||
- [ ] Espacio en disco suficiente
|
||
- [ ] Permisos de archivo correctos
|
||
- [ ] Dependencias Python instaladas
|
||
- [ ] Zona horaria correcta
|
||
- [ ] Configuración de reportes válida
|
||
|
||
## Mejores Prácticas
|
||
|
||
### Prevención
|
||
|
||
1. **Validación de Configuración:** Verificar al inicio
|
||
2. **Health Checks:** Monitorear componentes críticos
|
||
3. **Backup:** Mantener copias de configuraciones
|
||
4. **Versionado:** Control de cambios en config
|
||
|
||
### Respuesta
|
||
|
||
1. **Documentar Incidentes:** Registrar causa y resolución
|
||
2. **Automatizar Recuperación:** Scripts para reintentos
|
||
3. **Escalada:** Definir cuándo notificar a equipo
|
||
4. **Post-mortem:** Análisis después de incidentes críticos
|
||
|
||
### Mejora Continua
|
||
|
||
1. **Métricas:** Recopilar estadísticas de errores
|
||
2. **Análisis de Tendencias:** Identificar patrones
|
||
3. **Optimización:** Reducir puntos de fallo
|
||
4. **Testing:** Cobertura de escenarios de error |