AutomationFlowsWeb Scraping › Robust API Error Handling Workflow

Robust API Error Handling Workflow

Original n8n title: Error Handling

Error Handling. Uses start, json, httpRequest. Manual trigger; 9 nodes.

Manual trigger★★★★☆ complexity9 nodesStartJSONHTTP Request
Web Scraping Trigger: Manual Nodes: 9 Complexity: ★★★★☆ Added:

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Error Handling",
  "description": "Comprehensive error handling patterns for robust workflow execution",
  "category": "advanced-patterns",
  "difficulty": "advanced",
  "estimatedTime": "20 minutes",
  "prerequisites": [
    "Advanced n8n knowledge",
    "Error handling concepts"
  ],
  "learningObjectives": [
    "Master error handling techniques",
    "Learn retry patterns",
    "Practice graceful degradation"
  ],
  "nodes": [
    {
      "parameters": {},
      "id": "start",
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "assignments": [
          {
            "name": "apiEndpoints",
            "value": "[\"https://jsonplaceholder.typicode.com/users\", \"https://httpstat.us/500\", \"https://api.github.com/users/octocat\", \"https://invalid-url-that-will-fail.com/api\"]"
          }
        ]
      },
      "id": "set-test-endpoints",
      "name": "Set Test Endpoints",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        460,
        300
      ]
    },
    {
      "parameters": {
        "operation": "parse",
        "jsonPath": "$json.apiEndpoints",
        "includeItemIndex": true
      },
      "id": "split-endpoints",
      "name": "Split Endpoints",
      "type": "n8n-nodes-base.json",
      "typeVersion": 1,
      "position": [
        680,
        300
      ]
    },
    {
      "parameters": {
        "url": "{{ $json.data }}",
        "method": "GET",
        "options": {
          "timeout": 5000,
          "retry": {
            "enabled": true,
            "maxRetries": 3,
            "retryDelay": 1000
          }
        }
      },
      "id": "api-request",
      "name": "API Request",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        900,
        300
      ],
      "continueOnFail": true
    },
    {
      "parameters": {
        "conditions": [
          {
            "field": "error",
            "operation": "exists",
            "value": false
          }
        ]
      },
      "id": "check-success",
      "name": "Check Success",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 1,
      "position": [
        1120,
        300
      ]
    },
    {
      "parameters": {
        "assignments": [
          {
            "name": "status",
            "value": "success"
          },
          {
            "name": "endpoint",
            "value": "{{ $node('Split Endpoints').json.data }}"
          },
          {
            "name": "responseSize",
            "value": "{{ length(JSON.stringify($json)) }}"
          },
          {
            "name": "processedAt",
            "value": "{{ formatDate(now(), 'yyyy-MM-dd HH:mm:ss') }}"
          }
        ]
      },
      "id": "handle-success",
      "name": "Handle Success",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        1340,
        200
      ]
    },
    {
      "parameters": {
        "assignments": [
          {
            "name": "status",
            "value": "error"
          },
          {
            "name": "endpoint",
            "value": "{{ $node('Split Endpoints').json.data }}"
          },
          {
            "name": "errorType",
            "value": "{{ $json.error ? $json.error.name : 'Unknown' }}"
          },
          {
            "name": "errorMessage",
            "value": "{{ $json.error ? $json.error.message : 'Request failed' }}"
          },
          {
            "name": "httpStatus",
            "value": "{{ $json.error && $json.error.httpCode ? $json.error.httpCode : 'N/A' }}"
          },
          {
            "name": "failedAt",
            "value": "{{ formatDate(now(), 'yyyy-MM-dd HH:mm:ss') }}"
          },
          {
            "name": "retryable",
            "value": "{{ $json.error && $json.error.httpCode && $json.error.httpCode >= 500 }}"
          }
        ]
      },
      "id": "handle-error",
      "name": "Handle Error",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        1340,
        400
      ]
    },
    {
      "parameters": {
        "operation": "merge",
        "mergeSources": [
          "$node('Handle Success').json",
          "$node('Handle Error').json"
        ]
      },
      "id": "merge-results",
      "name": "Merge Results",
      "type": "n8n-nodes-base.json",
      "typeVersion": 1,
      "position": [
        1560,
        300
      ]
    },
    {
      "parameters": {
        "assignments": [
          {
            "name": "summary",
            "value": "{{ {totalRequests: length($input.all()), successCount: length($input.all().filter(item => item.status === 'success')), errorCount: length($input.all().filter(item => item.status === 'error')), retryableErrors: length($input.all().filter(item => item.retryable === true))} }}"
          },
          {
            "name": "successRate",
            "value": "{{ round((length($input.all().filter(item => item.status === 'success')) / length($input.all())) * 100, 2) }}"
          },
          {
            "name": "reportGenerated",
            "value": "{{ formatDate(now(), 'yyyy-MM-dd HH:mm:ss') }}"
          }
        ]
      },
      "id": "generate-summary",
      "name": "Generate Summary",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        1780,
        300
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Set Test Endpoints",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Test Endpoints": {
      "main": [
        [
          {
            "node": "Split Endpoints",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Endpoints": {
      "main": [
        [
          {
            "node": "API Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "API Request": {
      "main": [
        [
          {
            "node": "Check Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Success": {
      "main": [
        [
          {
            "node": "Handle Success",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Handle Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Handle Success": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Handle Error": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge Results": {
      "main": [
        [
          {
            "node": "Generate Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {},
  "versionId": "1"
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Error Handling. Uses start, json, httpRequest. Manual trigger; 9 nodes.

Source: https://github.com/neul-labs/m9m/blob/main/examples/advanced-patterns/error-handling.json — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

API Integration. Uses start, httpRequest, json. Manual trigger; 4 nodes.

Start, HTTP Request, JSON
Web Scraping

FTS. Uses httpRequest, itemLists, functionItem, start. Manual trigger; 16 nodes.

HTTP Request, Item Lists, Function Item +1
Web Scraping

CBPF. Uses start, httpRequest, itemLists. Manual trigger; 13 nodes.

Start, HTTP Request, Item Lists
Web Scraping

Claude Prompt Pre-Processor (Pro V2). Uses start, httpRequest, returnJson. Manual trigger; 10 nodes.

Start, HTTP Request, Return Json
Web Scraping

DeepSeek Prompt Pre-Processor (Pro V2). Uses start, httpRequest, returnJson. Manual trigger; 10 nodes.

Start, HTTP Request, Return Json