mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-03-08 10:03:31 +01:00
Phase 5 - BYOB Backend (TASK-007A/B): - LocalSQL Adapter with full CloudStore API compatibility - QueryBuilder translates Parse-style queries to SQL - SchemaManager with PostgreSQL/Supabase export - LocalBackendServer with REST endpoints - BackendManager with IPC handlers for Electron - In-memory fallback when better-sqlite3 unavailable Phase 3 - GitHub Panel (GIT-004): - Issues tab with list/detail views - Pull Requests tab with list/detail views - GitHub API client with OAuth support - Repository info hook integration Phase 3 - Editor UX Bugfixes (TASK-013): - Legacy runtime detection banners - Read-only enforcement for legacy projects - Code editor modal close improvements - Property panel stuck state fix - Blockly node deletion and UI polish Phase 11 - Cloud Functions Planning: - Architecture documentation for workflow automation - Execution history storage schema design - Canvas overlay concept for debugging Docs: Updated LEARNINGS.md and COMMON-ISSUES.md
CF11-002: Error Handling Nodes (Try/Catch/Retry)
Metadata
| Field | Value |
|---|---|
| ID | CF11-002 |
| Phase | Phase 11 |
| Series | 1 - Advanced Workflow Nodes |
| Priority | 🟡 High |
| Difficulty | 🟡 Medium |
| Estimated Time | 8-10 hours |
| Prerequisites | Phase 5 TASK-007C (Workflow Runtime) |
| Branch | feature/cf11-002-error-nodes |
Objective
Create error handling nodes for workflows: Try/Catch for graceful error recovery and Retry for transient failure handling - critical for building reliable automation.
Background
External API calls fail. Databases timeout. Services go down. Production workflows need error handling:
- Try/Catch: Wrap operations and handle failures gracefully
- Retry: Automatically retry failed operations with configurable backoff
- Stop/Error: Explicitly fail a workflow with a message
Without these, any external failure crashes the entire workflow.
Scope
In Scope
- Try/Catch Node implementation
- Retry Node implementation
- Stop/Error Node implementation
- Configurable retry strategies
Out of Scope
- Global error handlers (future)
- Error reporting/alerting (future)
Technical Approach
Try/Catch Node
const TryCatchNode = {
name: 'Workflow Try Catch',
displayName: 'Try / Catch',
category: 'Workflow Logic',
inputs: {
run: { type: 'signal', displayName: 'Try' }
},
outputs: {
try: { type: 'signal', displayName: 'Try Block' },
catch: { type: 'signal', displayName: 'Catch Block' },
finally: { type: 'signal', displayName: 'Finally' },
error: { type: 'object', displayName: 'Error' },
success: { type: 'boolean', displayName: 'Success' }
},
async run(context) {
try {
await context.triggerOutputAndWait('try');
context.outputs.success = true;
} catch (error) {
context.outputs.error = { message: error.message, stack: error.stack };
context.outputs.success = false;
context.triggerOutput('catch');
} finally {
context.triggerOutput('finally');
}
}
};
Retry Node
const RetryNode = {
name: 'Workflow Retry',
displayName: 'Retry',
category: 'Workflow Logic',
inputs: {
run: { type: 'signal' },
maxAttempts: { type: 'number', default: 3 },
delayMs: { type: 'number', default: 1000 },
backoffMultiplier: { type: 'number', default: 2 }
},
outputs: {
attempt: { type: 'signal', displayName: 'Attempt' },
success: { type: 'signal' },
failure: { type: 'signal' },
attemptNumber: { type: 'number' },
lastError: { type: 'object' }
},
async run(context) {
const maxAttempts = context.inputs.maxAttempts || 3;
const baseDelay = context.inputs.delayMs || 1000;
const multiplier = context.inputs.backoffMultiplier || 2;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
context.outputs.attemptNumber = attempt;
try {
await context.triggerOutputAndWait('attempt');
context.triggerOutput('success');
return;
} catch (error) {
context.outputs.lastError = { message: error.message };
if (attempt < maxAttempts) {
const delay = baseDelay * Math.pow(multiplier, attempt - 1);
await sleep(delay);
}
}
}
context.triggerOutput('failure');
}
};
Stop/Error Node
const StopNode = {
name: 'Workflow Stop',
displayName: 'Stop / Error',
category: 'Workflow Logic',
inputs: {
run: { type: 'signal' },
errorMessage: { type: 'string', default: 'Workflow stopped' },
isError: { type: 'boolean', default: true }
},
run(context) {
const message = context.inputs.errorMessage || 'Workflow stopped';
if (context.inputs.isError) {
throw new WorkflowError(message);
}
// Non-error stop - just terminates this path
}
};
Implementation Steps
- Try/Catch Node (3h) - Error boundary, output routing
- Retry Node (3h) - Attempt loop, backoff logic, timeout handling
- Stop/Error Node (1h) - Simple error throwing
- Testing (2h) - Unit tests, integration tests
Success Criteria
- Try/Catch captures downstream errors
- Retry attempts with exponential backoff
- Stop/Error terminates workflow with message
- Error data captured in execution history
References
- CF11-001 Logic Nodes - Same patterns
- n8n Error Handling