Bulletproof Workflows
Module 04 · foundations · intermediate
learner.json
In n8n, copy this file and paste it onto the canvas, or use Import from File.
{
"name": "04 - Safe Divide API",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "divide",
"responseMode": "responseNode",
"options": {}
},
"id": "m04-webhook",
"name": "Divide API",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
0,
100
],
"webhookId": "course-04-divide"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "n1",
"leftValue": "={{ $json.body.a !== '' && $json.body.b !== '' && Number.isFinite(Number($json.body.a)) && Number.isFinite(Number($json.body.b)) }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "m04-valid",
"name": "Numbers?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
220,
100
]
},
{
"parameters": {
"workflowId": {
"__rl": true,
"mode": "id",
"value": "__WF_ID:learner-sub.json__"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"a": "={{ Number($json.body.a) }}",
"b": "={{ Number($json.body.b) }}"
},
"matchingColumns": [],
"schema": [
{
"id": "a",
"displayName": "a",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "number",
"removed": false
},
{
"id": "b",
"displayName": "b",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "number",
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": true
},
"options": {
"waitForSubWorkflow": true
}
},
"id": "m04-exec",
"name": "Divide (sub-workflow)",
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.2,
"position": [
440,
0
],
"onError": "continueErrorOutput"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ { result: $json.result } }}",
"options": {}
},
"id": "m04-ok",
"name": "Respond OK",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
700,
-100
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ { error: $json.error } }}",
"options": {
"responseCode": 422
}
},
"id": "m04-422",
"name": "Respond Calculation Error",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
700,
100
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ { error: 'a and b must be numbers' } }}",
"options": {
"responseCode": 400
}
},
"id": "m04-400",
"name": "Respond Bad Input",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
440,
250
]
},
{
"parameters": {
"httpMethod": "POST",
"path": "crash",
"options": {},
"responseMode": "lastNode"
},
"id": "m04-crash-webhook",
"name": "Crash API",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
0,
450
],
"webhookId": "course-04-crash"
},
{
"parameters": {
"errorMessage": "Simulated crash to test the Error Workflow"
},
"id": "m04-crash",
"name": "Simulate Crash",
"type": "n8n-nodes-base.stopAndError",
"typeVersion": 1,
"position": [
220,
450
]
}
],
"connections": {
"Divide API": {
"main": [
[
{
"node": "Numbers?",
"type": "main",
"index": 0
}
]
]
},
"Numbers?": {
"main": [
[
{
"node": "Divide (sub-workflow)",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond Bad Input",
"type": "main",
"index": 0
}
]
]
},
"Divide (sub-workflow)": {
"main": [
[
{
"node": "Respond OK",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond Calculation Error",
"type": "main",
"index": 0
}
]
]
},
"Crash API": {
"main": [
[
{
"node": "Simulate Crash",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1",
"errorWorkflow": "__WF_ID:learner-error.json__"
}
}