PTENES
MODULE 4.4

🛡️ Reliability

What separates a toy from a service customers pay for: error handling, retries and timeouts, idempotency to prevent duplicates, observability with logs and alerts, staging tests, and a final checklist before going to production.

6
Topics
50
Minutes
Intermediate
Level
Hands-on practice
Type
Trigger Action + retry 3 attempts Success ✓ on error Error workflow Slack alert Log

Illustrative — success continues to the right; failure goes to the error branch, which sends an alert and logs the event.

1

🚨 Error handling

In production, everything eventually fails. Whoever handles errors is notified; those who don’t handle it find out from an angry customer. Use a error workflow global, the node’s error branch, or continue on fail.

# Error Trigger — workflow dedicated to failures
// disparado automaticamente quando QUALQUER fluxo falha
Workflow:  ={{ $json.workflow.name }}
Node:      ={{ $json.execution.lastNodeExecuted }}
Erro:      ={{ $json.execution.error.message }}
// → manda esse resumo pro Slack

✓ Error-handling flow

  • ✓A global error workflow notifies you of every failure.
  • ✓continue on fail in a non-critical node.
  • ✓The error branch logs the problematic item.

✗ Flow that fails silently

  • ✗Without an error workflow, failures go unnoticed.
  • ✗One bad item brings down the entire batch.
  • ✗No one gets notified; the client finds out first.
2

⏱️ Retries and timeouts

Many failures are transient — unstable API, network timeout. A retry with backoff turns "there was an error" into "it fixed itself on the 2nd attempt." But set a timeout: waiting forever stalls the workflow.

# retry configuration in the node (settings)
Retry On Fail:      true
Max Tries:          3
Wait Between Tries: 2000 ms   // idealmente crescente (backoff)
Timeout:            30000 ms  // não espere para sempre

📊 Retry with care

  • Backoff - wait longer after each attempt (2s, 4s, 8s) so you don't hammer the API.
  • Transient data only - 5xx and timeout are worth retrying; 400/401 aren’t (they’ll fail the same way).
  • Attempt limit - 3 to 5; then go to the error branch and alert.
3

🧬 Idempotency and preventing duplicates

Retries and webhooks redeliver. Without idempotency, every retry becomes a duplicate—two records, two emails, the same charge 3x. Idempotent = running the same input twice has the same effect as running it once.

# UPSERT with an idempotency key instead of a blind INSERT
// chave idempotente derivada do evento
chave = ={{ $json.pedido_id + '-' + $json.tipo_evento }}

// UPSERT: se a chave já existe, atualiza; senão, cria
// → reenvio do mesmo evento não duplica
1

Define an idempotency key

A stable event identifier (e.g., request_id) that doesn’t change between retries.

2

Check before acting

SELECT by key before inserting, or use UPSERT, which handles this in the database.

3

Deduplicate before notifying

Mark "already sent" so a retry doesn’t send the same email again.

4

📡 Observability: logs and alerts

You can’t fix what you can’t see. Structured logs record what each execution did; alerts proactive systems alert you when something fails. The difference between 5 minutes and 5 hours of losses.

# alert Slack when something fails
POST ={{ $env.SLACK_ALERT_WEBHOOK }}
{ "text": "🚨 Falha no fluxo *={{ $json.workflow.name }}*\n
            Node: ={{ $json.execution.lastNodeExecuted }}\n
            Erro: ={{ $json.execution.error.message }}" }
Structured log

What ran, and when

Alert

Slack / email on failure

Metric

Success rate

History

Execution history

💡 Practical tip

Alert on failure, not on success—otherwise it becomes noise and you stop reading. And never log the API key: mask secrets before writing any line.

5

🧪 Testing and staging environment

Testing directly in production breaks the customer's live service. A staging with test data is your safety net: validate the change there before touching what’s running.

✓ With user acceptance testing

  • ✓Separate credentials and test data (ENVIRONMENT=staging).
  • ✓Smoke test after each change: run 1 case and check it.
  • ✓Pin data with edge cases (null field, huge value).

✗ Testing in production

  • ✗Send a test email to real customers.
  • ✗Edit the active flow without a backup.
  • ✗Discovering the bug only when real volume arrives.

📊 What to test before promoting

  • Happy path - normal input produces the expected action.
  • Edge cases - missing field, empty list, unexpected value.
  • Simulated failure - deliberately take the API down and watch the error branch work.
6

✅ Production checklist

The checklist turns “I think it’s ready” into “it’s ready”—and it’s what you show the client as guarantee. Before you turn it on for real, go through each item.

🚀 Go-live checklist

☐Handled errors (error workflow active)
☐Retries with defined backoff and timeout
☐Guaranteed idempotency (no duplicates)
☐Failure alerts pointing to a real channel
☐Secrets in $env/credential, nothing hardcoded
☐Nulls handled in expressions
☐Tested in staging (happy path + edge case + failure)
☐Rollback plan and responsible owner defined

💡 Practical tip

Always have a rollback plan: how to turn off the automation and return to the manual process in 1 click if something goes very wrong. That’s what gives you (and the client) the confidence to turn on the workflow.

📌 Module Summary

✓
Error handling - global error workflow; whoever handles it is notified, whoever doesn't finds out too late.
✓
Retries and timeouts - use backoff only for transient failures; always set a cap and timeout.
✓
Idempotency - a stable key + UPSERT prevent duplicates on resubmission.
✓
Observability - structured log and alert on failure; never log secrets.
✓
Acceptance testing - test in staging with happy-path, edge, and failure cases before promoting.
✓
Production checklist - go-live + rollback turn "I think" into a guarantee.

Next Track:

Track 5 · Sales - package, price, and sell your automation as a service.