跳到正文
DEV Community· Robert Breen·· 3 小時前AI 評分59

n8n 如何重試 429 或 500,並對 401 快速失敗:HTTP 狀態碼、Retry On Fail 與 Error output

n8n: Retry a 429 or a 500, Fail Fast on a 401. HTTP Status Codes, Retry On Fail and the Error Output

AI 導讀

Robert Breen 的 n8n 教學示範如何按 HTTP 狀態碼設定重試、快速失敗及錯誤告警。n8n 的 Retry On Fail 會重試所有狀態碼;要只重試 429 和 5xx,可回傳狀態碼後分流,其他錯誤則停止流程。文中亦示範按 Retry-After 設定等待時間,上限為 60 秒,並以 Error output 或 Error Workflow 發送告警。

正文

The most common way an n8n workflow fails in a small business isn't a bug. It's a supplier's server being busy at 6 AM. A workflow runs on a schedule, the HTTP Request step gets an error, the run stops, and nobody finds out until someone opens a spreadsheet that didn't update.

The second most common way is the opposite. An API key expired, and the workflow retries the same rejected request again and again, every morning, quietly.

Both come down to reading one number: the HTTP status code.

The one-digit rule

An HTTP status code is the three-digit number a server sends back with every response to say how the request went. You don't need to memorize them. Look at the first digit:

  • 2xx: it worked.
  • 4xx: something was wrong with the request you sent.
  • 5xx: the server had a problem.

That maps straight onto what to do:

Code Meaning What I do in n8n
200 OK Nothing. Read the body if the data looks wrong.
400 Bad request Fail. Compare the URL, query and body with the API's own example.
401 / 403 Not allowed Fail and alert. Reconnect the credential or check permissions. Retrying won't fix it.
404 Nothing at that address Fail, or branch if "not found" is a normal answer.
429 Too many requests Retry after a pause.
500 / 502 / 503 Server problem Retry after a pause, then alert.

One trap: OpenAI can return a 429 when the account has no credit left. Slowing down won't fix that one. Add credit.

The easy version: Retry On Fail

Every n8n node has a Settings tab. Turn on Retry On Fail and two fields appear:

  • Max. Tries: attempts in all, from 2 to 5, starting at 3.
  • Wait Between Tries (ms): the pause between attempts, from 0 to 5000, starting at 1000.

In my error handling lesson, Maple Lane Florist's Supplier price check runs at 6 every morning. You open its HTTP Request step, turn on Retry On Fail, keep Max. Tries at 3 and change the wait to 5000, the highest it allows. Each retry now gives the supplier five seconds to recover.

On the same tab, On Error decides what happens after the last try fails:

  • Stop Workflow (default): the run fails, which is what triggers your error workflow.
  • Continue: the error is passed along as an item, as if it were data.
  • Continue (using error output): the step gets a second output, labelled Error, next to Success.

In the workflow JSON, those settings sit on the node itself:

{
  "parameters": {
    "url": "https://api.example.com/prices",
    "options": {}
  },
  "name": "Get supplier prices",
  "type": "n8n-nodes-base.httpRequest",
  "typeVersion": 4.2,
  "position": [240, 0],
  "retryOnFail": true,
  "maxTries": 3,
  "waitBetweenTries": 5000,
  "onError": "continueErrorOutput"
}

Wire the Error output to a Gmail Send a message step, and the owner hears about it while the rest of the run carries on.

One thing to know: a step with an Error output no longer fails the run, so your error workflow won't hear about it. The Error output is its alert.

The catch: Retry On Fail retries everything

Retry On Fail doesn't look at the code. A 401 gets retried three times, five seconds apart, exactly like a 503. It's harmless, but it's slow, and it hides the fact that this failure needs a person, not a pause.

If you want to retry only 429 and 5xx, and fail fast on everything else, make the node return the status code instead of failing, then decide yourself.

The precise version: route by status code

1. Return the status, don't throw

In the HTTP Request node, under Options, Response, turn on Include Response Headers and Status and Never Error. The node now succeeds whatever the code was and hands you statusCode, headers and body.

{
  "parameters": {
    "url": "https://api.example.com/prices",
    "options": {
      "response": {
        "response": {
          "fullResponse": true,
          "neverError": true
        }
      }
    }
  },
  "name": "Get supplier prices",
  "type": "n8n-nodes-base.httpRequest",
  "typeVersion": 4.2,
  "position": [240, 0]
}

Never Error is only safe when something after it checks the code. On its own, it just makes failures silent.

2. Sort the response in a Code node

Add a Code node after it, mode Run Once for Each Item:

// Decide what to do with this HTTP response
const MAX_ATTEMPTS = 3;
const code = Number($json.statusCode);
const attempt = $runIndex + 1;   // how many times this node has run in this execution

let action;
if (code >= 200 && code < 300) {
  action = 'ok';
} else if (code === 429 || code >= 500) {
  action = attempt < MAX_ATTEMPTS ? 'retry' : 'give_up';
} else {
  action = 'fail';                 // 400, 401, 403, 404...: retrying won't help
}

// Respect Retry-After (seconds) if the server sent it, capped at 60
const retryAfter = Number($json.headers?.['retry-after']);
const waitSeconds = Number.isFinite(retryAfter) && retryAfter > 0
  ? Math.min(retryAfter, 60)
  : 5 * attempt;                   // 5s, 10s, 15s

return {
  json: {
    ...$json,
    action,
    attempt,
    waitSeconds,
  },
};

$runIndex counts how many times this node has already run in the current execution, so it doubles as a retry counter when you loop back.

3. Switch on the action

Add a Switch node in Rules mode on {{ $json.action }}, with one rule each for ok, retry and fail, and rename the outputs to match. Under Options, add Fallback Output and choose Extra Output, so give_up (and anything unexpected) lands somewhere instead of disappearing.

  • ok: continue to your Google Sheets step.
  • retry: a Wait node set to {{ $json.waitSeconds }} seconds, connected back to the HTTP Request node.
  • fail: a Stop and Error node with a message like Supplier API returned {{ $json.statusCode }}. The run fails, so your error workflow fires.
  • Fallback: also a Stop and Error, saying the API still failed after the last attempt.

The Stop and Error branches are what make this better than Never Error alone. A real failure still fails the run, loudly.

The safety net: an error workflow

Whichever version you use, set an error workflow. In a new workflow, add the Error Trigger node and a Gmail Send a message with:

Workflow: {{ $json.workflow.name }}
Error: {{ $json.execution.error.message }}
Run: {{ $json.execution.url }}

Publish it, then in each workflow open the three-dot menu, Settings, pick it under Error Workflow (to notify when this one errors) and Save. Two rules catch people out: error workflows only run for automatic, production runs, never for a manual test, and in n8n 2.40 the list only shows published workflows.

Where not to retry

Use retries on steps that read from another service. Skip them on steps that would do harm if they ran twice, like charging a card or sending a customer email. A 500 from a payment API doesn't always mean the charge didn't happen.

If you're setting up n8n for this, you can try n8n here (affiliate link: I may earn a commission, at no cost to you).

Try it free

The HTTP status code glossary page has the short table and a worked webhook example. To practice the retry and alert settings on a real-looking workflow, the lesson Get Alerted When an n8n Automation Fails, and Let It Retry by Itself walks through Retry On Fail, the Error output and the Executions tab in 31 steps.

Practice it step by step, free: https://learn.ynteractive.com/content/glossary/http-status-code

來源:DEV Community · dev.to