Tratamento de Erros
O tratamento de erros é fundamental para criar workflows robustos e confiáveis no n8n. Este guia aborda estratégias, técnicas e ferramentas para implementar tratamento de erros eficiente.
Conceitos Fundamentais
Por que Tratar Erros
Tratar erros adequadamente garante:
- Confiabilidade: Workflows que continuam funcionando mesmo com falhas
- Observabilidade: Visibilidade sobre problemas e suas causas
- Recuperação: Capacidade de se recuperar automaticamente
- Manutenibilidade: Facilita debugging e correção de problemas
Tipos de Erros
1. Erros de Conectividade
{
"error": {
"type": "connection",
"code": "ECONNREFUSED",
"message": "Connection refused",
"node": "HTTP Request",
"timestamp": "2024-01-20T10:00:00Z"
}
}
2. Erros de Autenticação
{
"error": {
"type": "authentication",
"code": "401",
"message": "Unauthorized",
"node": "Gmail",
"timestamp": "2024-01-20T10:00:00Z"
}
}
3. Erros de Dados
{
"error": {
"type": "data",
"code": "VALIDATION_ERROR",
"message": "Required field missing",
"node": "Set",
"timestamp": "2024-01-20T10:00:00Z"
}
}
4. Erros de Rate Limiting
{
"error": {
"type": "rate_limit",
"code": "429",
"message": "Too Many Requests",
"node": "API Request",
"timestamp": "2024-01-20T10:00:00Z"
}
}
Estratégias de Tratamento
1. Try-Catch Pattern
Implementação com IF Node
{
"node": {
"type": "n8n-nodes-base.if",
"name": "Error Handler",
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.error }}",
"operation": "exists"
}
]
}
}
}
}
Implementação com Code Node
// Code Node para tratamento de erros
try {
// Operação que pode falhar
const result = await someOperation();
return { success: true, data: result };
} catch (error) {
// Tratamento do erro
console.error('Error occurred:', error);
return {
success: false,
error: error.message,
timestamp: new Date().toISOString()
};
}
2. Retry Logic
Configuração de Retry
{
"retry": {
"attempts": 3,
"delay": 5000,
"backoff": "exponential",
"maxDelay": 30000,
"conditions": [
"network_error",
"rate_limit",
"temporary_failure"
]
}
}
Retry Customizado
// Code Node para retry inteligente
const maxAttempts = 3;
const currentAttempt = $execution.attempt || 1;
if (currentAttempt < maxAttempts) {
// Calcular delay exponencial
const delay = Math.pow(2, currentAttempt) * 1000;
// Aguardar antes da próxima tentativa
await new Promise(resolve => setTimeout(resolve, delay));
// Lançar erro para forçar retry
throw new Error(`Retry attempt ${currentAttempt}`);
}
// Se chegou aqui, é a última tentativa
return items;
3. Circuit Breaker Pattern
Implementação
// Code Node para Circuit Breaker
const circuitBreaker = {
failureThreshold: 5,
recoveryTimeout: 60000,
state: 'CLOSED', // CLOSED, OPEN, HALF_OPEN
failureCount: 0,
lastFailureTime: null
};
// Verificar estado do circuit breaker
if (circuitBreaker.state === 'OPEN') {
const timeSinceLastFailure = Date.now() - circuitBreaker.lastFailureTime;
if (timeSinceLastFailure > circuitBreaker.recoveryTimeout) {
circuitBreaker.state = 'HALF_OPEN';
} else {
throw new Error('Circuit breaker is OPEN');
}
}
try {
// Executar operação
const result = await riskyOperation();
// Sucesso - reset circuit breaker
if (circuitBreaker.state === 'HALF_OPEN') {
circuitBreaker.state = 'CLOSED';
}
circuitBreaker.failureCount = 0;
return result;
} catch (error) {
// Falha - incrementar contador
circuitBreaker.failureCount++;
circuitBreaker.lastFailureTime = Date.now();
if (circuitBreaker.failureCount >= circuitBreaker.failureThreshold) {
circuitBreaker.state = 'OPEN';
}
throw error;
}
Nodes Específicos para Tratamento de Erros
1. Error Trigger Node
Configuração
{
"node": {
"type": "n8n-nodes-base.errorTrigger",
"name": "Error Handler",
"parameters": {
"errorMessage": "={{ $json.error.message }}",
"errorType": "={{ $json.error.type }}",
"nodeName": "={{ $json.error.node }}"
}
}
}
Uso no Workflow
2. Set Node para Error Handling
Configuração de Error Context
{
"node": {
"type": "n8n-nodes-base.set",
"name": "Add Error Context",
"parameters": {
"values": {
"string": [
{
"name": "errorTimestamp",
"value": "={{ $now }}"
},
{
"name": "workflowName",
"value": "={{ $workflow.name }}"
},
{
"name": "executionId",
"value": "={{ $execution.id }}"
},
{
"name": "errorSeverity",
"value": "high"
}
]
}
}
}
}
3. HTTP Request para Error Reporting
Configuração de Webhook de Erro
{
"node": {
"type": "n8n-nodes-base.httpRequest",
"name": "Send Error Report",
"parameters": {
"method": "POST",
"url": "https://api.error-reporting.com/errors",
"authentication": "predefinedCredentialType",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "error",
"value": "={{ $json.error }}"
},
{
"name": "context",
"value": "={{ $json.context }}"
}
]
}
}
}
}
Padrões de Tratamento por Tipo de Erro
1. Erros de Rede
Detecção e Retry
// Code Node para tratamento de erros de rede
const isNetworkError = (error) => {
const networkErrors = [
'ECONNREFUSED',
'ENOTFOUND',
'ETIMEDOUT',
'ECONNRESET'
];
return networkErrors.includes(error.code) ||
error.message.includes('network') ||
error.message.includes('timeout');
};
try {
const result = await networkOperation();
return result;
} catch (error) {
if (isNetworkError(error)) {
// Implementar retry com backoff exponencial
const retryCount = $execution.attempt || 1;
const delay = Math.pow(2, retryCount) * 1000;
if (retryCount < 3) {
await new Promise(resolve => setTimeout(resolve, delay));
throw new Error('Retry network operation');
}
}
// Se não for erro de rede ou excedeu tentativas
throw error;
}
2. Erros de Rate Limiting
Implementação de Rate Limiting
// Code Node para tratamento de rate limiting
const handleRateLimit = async (error) => {
if (error.status === 429) {
// Extrair tempo de espera do header
const retryAfter = error.headers['retry-after'] || 60;
console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
// Retry a operação
throw new Error('Retry after rate limit');
}
throw error;
};
try {
const result = await apiCall();
return result;
} catch (error) {
await handleRateLimit(error);
}
3. Erros de Validação
Validação de Dados
// Code Node para validação e tratamento de erros
const validateData = (data) => {
const errors = [];
// Validar campos obrigatórios
if (!data.email) {
errors.push('Email is required');
}
if (!data.name) {
errors.push('Name is required');
}
// Validar formato de email
if (data.email && !isValidEmail(data.email)) {
errors.push('Invalid email format');
}
return errors;
};
const isValidEmail = (email) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
};
// Processar dados
const validationErrors = validateData($input.first().json);
if (validationErrors.length > 0) {
return {
success: false,
errors: validationErrors,
data: $input.first().json
};
}
// Dados válidos - continuar processamento
return {
success: true,
data: $input.first().json
};
Monitoramento e Alertas
1. Logging de Erros
Estrutura de Log
{
"log": {
"level": "error",
"timestamp": "2024-01-20T10:00:00Z",
"workflow": "Processamento de Pedidos",
"execution": "exec_12345",
"node": "HTTP Request",
"error": {
"type": "connection",
"message": "Connection refused",
"code": "ECONNREFUSED",
"stack": "..."
},
"context": {
"input": "dados de entrada",
"attempt": 3,
"retryCount": 2
}
}
}
2. Alertas Automáticos
Configuração de Alertas
{
"alerts": {
"critical": {
"conditions": [
"error_rate > 0.1",
"consecutive_failures > 5",
"execution_time > 300000"
],
"channels": ["email", "slack", "sms"],
"recipients": ["oncall@company.com"]
},
"warning": {
"conditions": [
"error_rate > 0.05",
"execution_time > 60000"
],
"channels": ["slack"],
"recipients": ["dev-team"]
}
}
}
3. Dashboard de Erros
Métricas Importantes
Error Rate:
- Total Errors: 25
- Error Rate: 2.5%
- Critical Errors: 5
- Warning Errors: 20
Error Types:
- Network: 40%
- Authentication: 25%
- Validation: 20%
- Rate Limiting: 15%
Top Error Sources:
- HTTP Request Node: 15 errors
- Gmail Node: 5 errors
- Database Node: 3 errors
- API Node: 2 errors
Melhores Práticas
1. Design de Workflows
Estrutura Recomendada
2. Nomenclatura e Organização
Convenções
Error Nodes:
- "Error Handler - [Tipo]"
- "Retry Logic - [Operação]"
- "Validation - [Dados]"
- "Notification - [Canal]"
Error Workflows:
- "Error Processing - [Contexto]"
- "Error Reporting - [Sistema]"
- "Error Recovery - [Processo]"
3. Documentação
Template de Documentação
# Error Handling Strategy
## Error Types
- **Network Errors**: Retry with exponential backoff
- **Authentication Errors**: Alert admin, disable workflow
- **Validation Errors**: Log and continue with default values
- **Rate Limiting**: Wait and retry
## Recovery Actions
- **Automatic**: Retry, circuit breaker, fallback
- **Manual**: Admin notification, workflow pause
- **Escalation**: SMS alert, phone call
## Monitoring
- **Metrics**: Error rate, response time, success rate
- **Alerts**: Email, Slack, SMS
- **Logs**: Structured logging with context
Exemplos Práticos
Exemplo 1: E-commerce Order Processing
Exemplo 2: Data Synchronization
// Code Node para sincronização com tratamento de erros
const syncData = async (source, destination) => {
const errors = [];
const successes = [];
for (const item of source) {
try {
// Tentar sincronizar item
const result = await syncItem(item, destination);
successes.push({ item, result });
} catch (error) {
// Registrar erro
errors.push({
item,
error: error.message,
timestamp: new Date().toISOString()
});
// Continuar com próximo item
continue;
}
}
return {
total: source.length,
successful: successes.length,
failed: errors.length,
errors: errors,
successes: successes
};
};
Recursos Adicionais
Documentação Oficial
Ferramentas de Debug
Comunidade
Próximos Passos: