0
# Error Handling
1
2
Structured error handling with specific error classes for different failure scenarios, including node errors, workflow errors, expression errors, and comprehensive error reporting capabilities.
3
4
## Capabilities
5
6
### Base Error Classes
7
8
Foundation error classes providing common error handling functionality.
9
10
```typescript { .api }
11
/**
12
* Base class for all execution-related errors
13
*/
14
abstract class ExecutionBaseError extends Error {
15
name: string;
16
message: string;
17
cause?: Error;
18
context?: IDataObject;
19
timestamp: Date;
20
21
constructor(message: string, options?: ErrorOptions);
22
23
/**
24
* Get error details for logging
25
* @returns Error details object
26
*/
27
getErrorDetails(): IErrorDetails;
28
}
29
30
/**
31
* Base class for node-related errors
32
*/
33
abstract class NodeError extends ExecutionBaseError {
34
node: INode;
35
itemIndex?: number;
36
runIndex?: number;
37
38
constructor(node: INode, message: string, options?: NodeErrorOptions);
39
}
40
41
/**
42
* Base class for workflow-related errors
43
*/
44
abstract class WorkflowError extends ExecutionBaseError {
45
workflow?: Workflow;
46
47
constructor(message: string, options?: WorkflowErrorOptions);
48
}
49
50
interface ErrorOptions {
51
cause?: Error;
52
context?: IDataObject;
53
}
54
55
interface NodeErrorOptions extends ErrorOptions {
56
itemIndex?: number;
57
runIndex?: number;
58
}
59
60
interface WorkflowErrorOptions extends ErrorOptions {
61
workflow?: Workflow;
62
}
63
```
64
65
### Node Operation Errors
66
67
Specific error classes for node execution failures and API errors.
68
69
```typescript { .api }
70
/**
71
* Error for node operation failures
72
*/
73
class NodeOperationError extends NodeError {
74
functionality: string;
75
76
constructor(
77
node: INode,
78
message: string,
79
options?: NodeOperationErrorOptions
80
);
81
82
/**
83
* Create error with recommendation
84
* @param node - Node that failed
85
* @param message - Error message
86
* @param functionality - Failed functionality description
87
* @returns Node operation error with recommendation
88
*/
89
static createWithRecommendation(
90
node: INode,
91
message: string,
92
functionality: string
93
): NodeOperationError;
94
}
95
96
/**
97
* Error for API-related node failures
98
*/
99
class NodeApiError extends NodeError {
100
httpCode?: number;
101
responseData?: any;
102
103
constructor(
104
node: INode,
105
httpRequestOptions: IHttpRequestOptions,
106
response?: any,
107
options?: NodeApiErrorOptions
108
);
109
110
/**
111
* Get HTTP status code
112
* @returns HTTP status code or undefined
113
*/
114
getHttpCode(): number | undefined;
115
116
/**
117
* Get response data
118
* @returns API response data
119
*/
120
getResponseData(): any;
121
}
122
123
/**
124
* Error for SSL/TLS related issues
125
*/
126
class NodeSSLError extends NodeError {
127
constructor(node: INode, cause: Error);
128
}
129
130
interface NodeOperationErrorOptions extends NodeErrorOptions {
131
functionality?: string;
132
recommendation?: string;
133
}
134
135
interface NodeApiErrorOptions extends NodeErrorOptions {
136
httpCode?: number;
137
responseData?: any;
138
}
139
```
140
141
### Workflow Errors
142
143
Error classes for workflow-level failures and operations.
144
145
```typescript { .api }
146
/**
147
* Error for workflow activation failures
148
*/
149
class WorkflowActivationError extends WorkflowError {
150
constructor(message: string, workflow: Workflow, cause?: Error);
151
}
152
153
/**
154
* Error for general workflow operation failures
155
*/
156
class WorkflowOperationError extends WorkflowError {
157
constructor(message: string, options?: WorkflowErrorOptions);
158
}
159
160
/**
161
* Error for workflow execution cancellation
162
*/
163
class ExecutionCancelledError extends WorkflowError {
164
constructor(message?: string);
165
}
166
```
167
168
### Expression Errors
169
170
Specialized errors for expression evaluation failures.
171
172
```typescript { .api }
173
/**
174
* Error for expression evaluation failures
175
*/
176
class ExpressionError extends Error {
177
description: string;
178
cause?: Error;
179
context?: IExpressionErrorContext;
180
181
constructor(
182
message: string,
183
options?: ExpressionErrorOptions
184
);
185
186
/**
187
* Get expression context information
188
* @returns Expression error context
189
*/
190
getContext(): IExpressionErrorContext | undefined;
191
}
192
193
interface IExpressionErrorContext {
194
expression: string;
195
itemIndex?: number;
196
runIndex?: number;
197
parameter?: string;
198
nodeName?: string;
199
}
200
201
interface ExpressionErrorOptions {
202
cause?: Error;
203
context?: IExpressionErrorContext;
204
description?: string;
205
}
206
```
207
208
### Error Reporter and Utilities
209
210
Error reporting and utility functions for error handling.
211
212
```typescript { .api }
213
/**
214
* Error reporter proxy for centralized error handling
215
*/
216
class ErrorReporterProxy {
217
/**
218
* Report error with context
219
* @param error - Error to report
220
* @param context - Additional context
221
*/
222
static report(error: Error, context?: IErrorContext): void;
223
224
/**
225
* Create error report
226
* @param error - Error to create report for
227
* @returns Error report object
228
*/
229
static createReport(error: Error): IErrorReport;
230
}
231
232
interface IErrorContext {
233
workflowId?: string;
234
executionId?: string;
235
nodeId?: string;
236
userId?: string;
237
additional?: IDataObject;
238
}
239
240
interface IErrorReport {
241
message: string;
242
stack?: string;
243
type: string;
244
context?: IErrorContext;
245
timestamp: Date;
246
level: 'error' | 'warning' | 'info';
247
}
248
249
/**
250
* Application-level error class
251
*/
252
class ApplicationError extends Error {
253
level: 'error' | 'warning' | 'info';
254
255
constructor(
256
message: string,
257
options?: ApplicationErrorOptions
258
);
259
}
260
261
interface ApplicationErrorOptions {
262
level?: 'error' | 'warning' | 'info';
263
cause?: Error;
264
tags?: string[];
265
}
266
```
267
268
### Error Analysis and Recovery
269
270
Functions for error analysis, categorization, and recovery suggestions.
271
272
```typescript { .api }
273
/**
274
* Analyze error and categorize
275
* @param error - Error to analyze
276
* @returns Error analysis result
277
*/
278
function analyzeError(error: Error): IErrorAnalysis;
279
280
/**
281
* Get error recovery suggestions
282
* @param error - Error to analyze
283
* @returns Array of recovery suggestions
284
*/
285
function getRecoverySuggestions(error: Error): IRecoverySuggestion[];
286
287
/**
288
* Check if error is retryable
289
* @param error - Error to check
290
* @returns Boolean indicating if error is retryable
291
*/
292
function isRetryableError(error: Error): boolean;
293
294
interface IErrorAnalysis {
295
category: 'network' | 'authentication' | 'validation' | 'configuration' | 'system' | 'unknown';
296
severity: 'low' | 'medium' | 'high' | 'critical';
297
isRetryable: boolean;
298
cause?: string;
299
affectedComponents: string[];
300
}
301
302
interface IRecoverySuggestion {
303
action: string;
304
description: string;
305
priority: 'high' | 'medium' | 'low';
306
automatic?: boolean;
307
}
308
309
/**
310
* Wrap function with error handling
311
* @param fn - Function to wrap
312
* @param errorHandler - Error handler function
313
* @returns Wrapped function with error handling
314
*/
315
function withErrorHandling<T extends (...args: any[]) => any>(
316
fn: T,
317
errorHandler: (error: Error) => void
318
): T;
319
```
320
321
### Error Formatting and Logging
322
323
Utilities for error formatting, serialization, and logging.
324
325
```typescript { .api }
326
/**
327
* Format error for display
328
* @param error - Error to format
329
* @param includeStack - Include stack trace
330
* @returns Formatted error string
331
*/
332
function formatError(error: Error, includeStack?: boolean): string;
333
334
/**
335
* Serialize error for storage/transmission
336
* @param error - Error to serialize
337
* @returns Serialized error object
338
*/
339
function serializeError(error: Error): ISerializedError;
340
341
/**
342
* Deserialize error from storage
343
* @param serializedError - Serialized error data
344
* @returns Reconstructed error object
345
*/
346
function deserializeError(serializedError: ISerializedError): Error;
347
348
interface ISerializedError {
349
name: string;
350
message: string;
351
stack?: string;
352
cause?: ISerializedError;
353
context?: IDataObject;
354
timestamp?: string;
355
[key: string]: any;
356
}
357
358
/**
359
* Create error with additional context
360
* @param originalError - Original error
361
* @param additionalContext - Additional context to add
362
* @returns Enhanced error with context
363
*/
364
function enhanceError(
365
originalError: Error,
366
additionalContext: IDataObject
367
): Error;
368
```
369
370
**Usage Examples:**
371
372
```typescript
373
import {
374
NodeOperationError,
375
NodeApiError,
376
ExpressionError,
377
WorkflowOperationError,
378
ErrorReporterProxy,
379
analyzeError,
380
withErrorHandling
381
} from "n8n-workflow";
382
383
// Node operation error
384
try {
385
// Node operation that might fail
386
const result = await performNodeOperation();
387
} catch (error) {
388
throw new NodeOperationError(
389
currentNode,
390
'Failed to process data: Invalid format',
391
{
392
functionality: 'Data Processing',
393
itemIndex: currentItemIndex,
394
cause: error
395
}
396
);
397
}
398
399
// API error handling
400
try {
401
const response = await this.helpers.httpRequest(requestOptions);
402
} catch (error) {
403
if (error.response) {
404
throw new NodeApiError(
405
currentNode,
406
requestOptions,
407
error.response,
408
{
409
httpCode: error.response.status,
410
responseData: error.response.data
411
}
412
);
413
} else {
414
throw new NodeOperationError(
415
currentNode,
416
`Network request failed: ${error.message}`
417
);
418
}
419
}
420
421
// Expression error
422
try {
423
const result = expression.resolveSimpleParameterValue(
424
"{{ $json.invalidProperty.nonExistent }}",
425
{},
426
'string'
427
);
428
} catch (error) {
429
throw new ExpressionError(
430
'Cannot access property of undefined',
431
{
432
cause: error,
433
context: {
434
expression: "{{ $json.invalidProperty.nonExistent }}",
435
itemIndex: 0,
436
nodeName: 'Data Transform'
437
}
438
}
439
);
440
}
441
442
// Workflow error
443
try {
444
await workflow.execute('manual');
445
} catch (error) {
446
throw new WorkflowOperationError(
447
'Workflow execution failed due to invalid configuration',
448
{
449
workflow,
450
cause: error
451
}
452
);
453
}
454
455
// Error reporting
456
try {
457
await riskOperation();
458
} catch (error) {
459
ErrorReporterProxy.report(error, {
460
workflowId: 'workflow-123',
461
executionId: 'exec-456',
462
nodeId: 'node-789',
463
additional: {
464
operation: 'data-sync',
465
timestamp: new Date().toISOString()
466
}
467
});
468
throw error;
469
}
470
471
// Error analysis and recovery
472
try {
473
await unreliableOperation();
474
} catch (error) {
475
const analysis = analyzeError(error);
476
477
console.log(`Error category: ${analysis.category}`);
478
console.log(`Severity: ${analysis.severity}`);
479
console.log(`Retryable: ${analysis.isRetryable}`);
480
481
if (analysis.isRetryable) {
482
const suggestions = getRecoverySuggestions(error);
483
suggestions.forEach(suggestion => {
484
console.log(`Recovery: ${suggestion.action} - ${suggestion.description}`);
485
});
486
}
487
}
488
489
// Function wrapping with error handling
490
const safeDatabaseOperation = withErrorHandling(
491
async (data: any) => {
492
return await database.save(data);
493
},
494
(error: Error) => {
495
console.error('Database operation failed:', error.message);
496
ErrorReporterProxy.report(error, { operation: 'database-save' });
497
}
498
);
499
500
// Usage with continue on fail
501
export async function execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
502
const items = this.getInputData();
503
const returnData: INodeExecutionData[] = [];
504
505
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
506
try {
507
const result = await processItem(items[itemIndex]);
508
returnData.push({ json: result });
509
} catch (error) {
510
if (this.continueOnFail()) {
511
returnData.push({
512
json: { error: error.message },
513
error: error instanceof NodeError ? error : new NodeOperationError(
514
this.getNode(),
515
error.message,
516
{ itemIndex, cause: error }
517
)
518
});
519
} else {
520
throw error;
521
}
522
}
523
}
524
525
return [returnData];
526
}
527
```