Error Handling Patterns
Camunda 8 tiene tres mecanismos de error distintos que interactúan: retries técnicos (FailJob), errores de negocio (ThrowError → BPMN boundary events), e incidents (resolución humana). Entender cuándo usar cada uno y cómo interactúan es crítico para un workflow engine correcto.
Los tres mecanismos¶
1. Retries técnicos (FailJob)¶
Cuando un worker encuentra un error técnico (timeout, servicio no disponible):
flowchart TD
Worker[Worker llama FailJob retries=N-1] --> Decide{retries?}
Decide -->|> 0 sin backoff| Reactivate[Job reactivado inmediatamente]
Decide -->|> 0 con backoff| Backoff[JobBackoffCheckScheduler reactiva después]
Decide -->|= 0| Incident[Se crea un INCIDENT]
Punto crítico: el worker DEBE decrementar retries manualmente. El engine no lo hace automáticamente. Esto es una decisión de diseño — el worker tiene control total sobre la política de retry.
Configuración en BPMN: <zeebe:taskDefinition retries="5" />
Ver concepts/retry-backoff para detalles del mecanismo interno.
2. Errores de negocio (ThrowError → BPMN Error Events)¶
Cuando un worker detecta un error de negocio (artículo agotado, pago rechazado):
flowchart TD
Worker[Worker llama ThrowError errorCode=GOOD_UNAVAILABLE] --> Boundary{Boundary error event matchea?}
Boundary -->|Sí| Alt[Activa camino alternativo]
Boundary -->|No| Term[TERMINA la instancia del proceso]
Diferencia crítica con incidents: un BPMN error no capturado termina la instancia. No crea un incident, no espera resolución humana. La instancia se pierde.
Esto significa que el modelador BPMN debe prever todos los errores de negocio posibles con boundary events. Si no, el proceso muere silenciosamente.
3. Incidents (resolución humana)¶
Los incidents se crean automáticamente cuando:
- Un job agota sus retries (JOB_NO_RETRIES)
- Un BPMN error event no se puede manejar internamente (UNHANDLED_ERROR_EVENT)
- La evaluación de una expresión falla (EXTRACT_VALUE_ERROR)
Ver concepts/incident-management para el mecanismo de resolución.
Flujo de decisión para workers¶
flowchart TD
Q{¿El error es técnico o de negocio?}
Q -->|TÉCNICO timeout, 503, network| Tech[FailJob retries-1, errorMessage<br/>Engine maneja retry/incident]
Q -->|NEGOCIO artículo agotado, saldo insuf.| Biz[ThrowError errorCode, errorMessage<br/>El proceso BPMN decide qué hacer]
Q -->|RESULTADO ESPERADO rama del proceso| Result[CompleteJob variables: result rejected<br/>Un XOR gateway evalúa el resultado]
Regla de oro: si el modelador BPMN debería decidir qué hacer → ThrowError. Si es un problema técnico transitorio → FailJob. Si es un resultado válido del negocio → CompleteJob con variable.
Idempotencia (at-least-once delivery)¶
Zeebe entrega jobs con semántica at-least-once: un job puede ejecutarse más de una vez si: - El worker se cae antes de completar - El timeout del job expira antes de que el worker responda - Hay un failover de partición
Tres estrategias de idempotencia:
| Estrategia | Ejemplo | Complejidad |
|---|---|---|
| Natural | confirmCustomer() produce el mismo resultado N veces |
Ninguna — ya es idempotente |
| Business | Verificar si la orden ya fue creada antes de crearla | Media — query antes de mutación |
| Custom | Transaction ID único por ejecución | Alta — requiere store de dedup |
Distributed Transactions (Sagas)¶
Las transacciones ACID no pueden abarcar sistemas distribuidos. Camunda modela "transacciones de negocio" con el patrón Saga:
flowchart LR
A[Service A OK] --> B[Service B OK]
B --> C[Service C FAIL]
C -.-> CB[Compensate B]
CB -.-> CA[Compensate A]
Implementación BPMN: - Cada service task tiene un compensation handler asociado - Si un paso falla, se ejecutan los handlers de compensación en orden inverso - BPMN compensation events modelan las operaciones de undo
Tres estrategias cuando hay inconsistencia temporal: 1. Ignorar: si el impacto es aceptable 2. Disculparse: reconocer y notificar 3. Resolver: restaurar consistencia activamente
Ver concepts/bpmn-execution-model para detalles de compensation behavior.
Patrones de integración y errores¶
La elección de patrón BPMN afecta el error handling:
| Patrón | Error handling |
|---|---|
| Service task (sync) | Retries + boundary error events |
| Send + receive (async) | Timer boundary para timeout, message boundary para errores |
| Event subprocess | Captura errores a nivel de scope, puede ser interrupting |
Implicaciones para el MVP¶
- Mantener los 3 mecanismos: retries, BPMN errors, incidents — son ortogonales y todos necesarios
- FailJob con decremento manual de retries: mantener — da control al worker
- BPMN error no capturado termina instancia: comportamiento correcto pero peligroso. Considerar log/alerta cuando esto pase
- Idempotencia: documentar como responsabilidad del worker, no del engine
- Compensation: clasificada como simplificable en analysis/mvp-feature-matrix — manual via error handling es suficiente para MVP
- At-least-once: mantener — es más simple que exactly-once y suficiente con workers idempotentes