0
# Static Utilities
1
2
VError provides a comprehensive set of static utility methods for error analysis, cause traversal, and error manipulation. These methods work with any Error objects, not just VError instances, making them useful for analyzing errors throughout your application.
3
4
## Capabilities
5
6
### VError.cause()
7
8
Retrieves the cause of any Error object, returning null if no cause exists.
9
10
```javascript { .api }
11
/**
12
* Get the cause of any Error object
13
* @param {Error} err - Error to inspect (must be an Error instance)
14
* @returns {Error|null} Cause error or null if no cause exists
15
*/
16
VError.cause(err);
17
```
18
19
**Usage Examples:**
20
21
```javascript
22
const VError = require('verror');
23
24
const originalError = new Error('file not found');
25
const chainedError = new VError(originalError, 'failed to read config');
26
27
console.log(VError.cause(chainedError) === originalError); // true
28
console.log(VError.cause(originalError)); // null (no cause)
29
30
// Works with any Error, not just VError
31
const regularError = new Error('regular error');
32
console.log(VError.cause(regularError)); // null
33
```
34
35
### VError.info()
36
37
Retrieves accumulated info properties from the entire error cause chain. Properties from deeper causes are overridden by properties from errors higher in the chain.
38
39
```javascript { .api }
40
/**
41
* Get accumulated info properties from entire error chain
42
* @param {Error} err - Error to inspect (must be an Error instance)
43
* @returns {Object} Merged info properties from cause chain (deeper causes first)
44
*/
45
VError.info(err);
46
```
47
48
**Usage Examples:**
49
50
```javascript
51
const VError = require('verror');
52
53
// Build error chain with info
54
const dbError = new VError({
55
info: {
56
host: 'db.example.com',
57
port: 5432,
58
database: 'users'
59
}
60
}, 'database connection failed');
61
62
const serviceError = new VError({
63
cause: dbError,
64
info: {
65
service: 'user-service',
66
operation: 'fetch-user',
67
port: 3000 // This overrides the port from dbError
68
}
69
}, 'service operation failed');
70
71
const info = VError.info(serviceError);
72
console.log(info);
73
// {
74
// host: 'db.example.com', // from dbError
75
// port: 3000, // from serviceError (overrides dbError.port)
76
// database: 'users', // from dbError
77
// service: 'user-service', // from serviceError
78
// operation: 'fetch-user' // from serviceError
79
// }
80
81
// Works with regular errors (returns empty object)
82
const regularError = new Error('regular error');
83
console.log(VError.info(regularError)); // {}
84
```
85
86
### VError.findCauseByName()
87
88
Searches through the error cause chain to find the first error with a specific name.
89
90
```javascript { .api }
91
/**
92
* Find first error in cause chain with specific name
93
* @param {Error} err - Error to search from (must be an Error instance)
94
* @param {string} name - Error name to find (must be non-empty string)
95
* @returns {Error|null} First matching error or null if not found
96
*/
97
VError.findCauseByName(err, name);
98
```
99
100
**Usage Examples:**
101
102
```javascript
103
const VError = require('verror');
104
105
// Create error chain with named errors
106
const dbError = new VError({ name: 'DatabaseError' }, 'connection failed');
107
const authError = new VError({
108
name: 'AuthenticationError',
109
cause: dbError
110
}, 'auth failed');
111
const apiError = new VError({
112
name: 'APIError',
113
cause: authError
114
}, 'request failed');
115
116
// Find specific errors in the chain
117
const foundDb = VError.findCauseByName(apiError, 'DatabaseError');
118
console.log(foundDb === dbError); // true
119
120
const foundAuth = VError.findCauseByName(apiError, 'AuthenticationError');
121
console.log(foundAuth === authError); // true
122
123
const notFound = VError.findCauseByName(apiError, 'NotFoundError');
124
console.log(notFound); // null
125
126
// Search from any point in the chain
127
const fromAuth = VError.findCauseByName(authError, 'DatabaseError');
128
console.log(fromAuth === dbError); // true
129
```
130
131
### VError.hasCauseWithName()
132
133
Checks if the error cause chain contains an error with a specific name.
134
135
```javascript { .api }
136
/**
137
* Check if cause chain contains error with specific name
138
* @param {Error} err - Error to search from (must be an Error instance)
139
* @param {string} name - Error name to find (must be non-empty string)
140
* @returns {boolean} True if error with given name exists in cause chain
141
*/
142
VError.hasCauseWithName(err, name);
143
```
144
145
**Usage Examples:**
146
147
```javascript
148
const VError = require('verror');
149
150
const dbError = new VError({ name: 'DatabaseError' }, 'connection failed');
151
const authError = new VError({
152
name: 'AuthenticationError',
153
cause: dbError
154
}, 'auth failed');
155
156
// Check for specific error types
157
console.log(VError.hasCauseWithName(authError, 'DatabaseError')); // true
158
console.log(VError.hasCauseWithName(authError, 'AuthenticationError')); // true
159
console.log(VError.hasCauseWithName(authError, 'NetworkError')); // false
160
161
// Useful for error handling logic
162
function handleError(err) {
163
if (VError.hasCauseWithName(err, 'DatabaseError')) {
164
console.log('Database issue detected, retrying...');
165
return retryOperation();
166
} else if (VError.hasCauseWithName(err, 'AuthenticationError')) {
167
console.log('Auth issue detected, redirecting to login...');
168
return redirectToLogin();
169
} else {
170
console.log('Unknown error type');
171
throw err;
172
}
173
}
174
```
175
176
### VError.fullStack()
177
178
Retrieves the complete stack trace including all errors in the cause chain.
179
180
```javascript { .api }
181
/**
182
* Get full stack trace including all causes in the chain
183
* @param {Error} err - Error to get stack from (must be an Error instance)
184
* @returns {string} Complete stack trace with all causes
185
*/
186
VError.fullStack(err);
187
```
188
189
**Usage Examples:**
190
191
```javascript
192
const VError = require('verror');
193
194
const originalError = new Error('file not found');
195
const chainedError = new VError(originalError, 'failed to read config');
196
const topError = new VError(chainedError, 'application startup failed');
197
198
// Get full stack trace
199
const fullStack = VError.fullStack(topError);
200
console.log(fullStack);
201
// Outputs something like:
202
// Error: application startup failed: failed to read config: file not found
203
// at Object.<anonymous> (/path/to/file.js:3:19)
204
// ... stack frames for topError
205
// caused by: VError: failed to read config: file not found
206
// at Object.<anonymous> (/path/to/file.js:2:21)
207
// ... stack frames for chainedError
208
// caused by: Error: file not found
209
// at Object.<anonymous> (/path/to/file.js:1:23)
210
// ... stack frames for originalError
211
212
// Compare with regular stack (only shows top error)
213
console.log(topError.stack);
214
// Only shows stack for topError, not the causes
215
```
216
217
### VError.errorFromList()
218
219
Converts an array of errors into a single error, using MultiError for multiple errors or returning the single error directly.
220
221
```javascript { .api }
222
/**
223
* Convert array of errors to single error
224
* @param {Error[]} errors - Array of Error objects
225
* @returns {Error|MultiError|null} Single error, MultiError for multiple, or null if empty
226
*/
227
VError.errorFromList(errors);
228
```
229
230
**Usage Examples:**
231
232
```javascript
233
const VError = require('verror');
234
235
// Empty array
236
console.log(VError.errorFromList([])); // null
237
238
// Single error
239
const singleError = new Error('single issue');
240
const result1 = VError.errorFromList([singleError]);
241
console.log(result1 === singleError); // true (returns the error directly)
242
243
// Multiple errors
244
const errors = [
245
new Error('validation failed for email'),
246
new Error('validation failed for age'),
247
new Error('validation failed for name')
248
];
249
const result2 = VError.errorFromList(errors);
250
console.log(result2 instanceof VError.MultiError); // true
251
console.log(result2.message); // "first of 3 errors"
252
253
// Useful for parallel operations
254
async function validateAllFields(data) {
255
const validationResults = await Promise.allSettled([
256
validateEmail(data.email),
257
validateAge(data.age),
258
validateName(data.name)
259
]);
260
261
const errors = validationResults
262
.filter(result => result.status === 'rejected')
263
.map(result => result.reason);
264
265
const finalError = VError.errorFromList(errors);
266
if (finalError) {
267
throw finalError;
268
}
269
270
return data; // All validations passed
271
}
272
```
273
274
### VError.errorForEach()
275
276
Iterates over individual errors, automatically handling MultiError by calling the function for each contained error.
277
278
```javascript { .api }
279
/**
280
* Iterate over individual errors (handles MultiError automatically)
281
* @param {Error} err - Error to iterate over (must be an Error instance)
282
* @param {Function} func - Function to call for each error
283
* @returns {undefined}
284
*/
285
VError.errorForEach(err, func);
286
```
287
288
**Usage Examples:**
289
290
```javascript
291
const VError = require('verror');
292
293
// Single error
294
const singleError = new Error('single issue');
295
VError.errorForEach(singleError, function(err) {
296
console.log('Error:', err.message);
297
});
298
// Output: "Error: single issue"
299
300
// MultiError
301
const multiError = new VError.MultiError([
302
new Error('validation failed for email'),
303
new Error('validation failed for age'),
304
new Error('validation failed for name')
305
]);
306
307
VError.errorForEach(multiError, function(err) {
308
console.log('Validation error:', err.message);
309
});
310
// Output:
311
// "Validation error: validation failed for email"
312
// "Validation error: validation failed for age"
313
// "Validation error: validation failed for name"
314
315
// Useful for logging all errors
316
function logAllErrors(err) {
317
VError.errorForEach(err, function(individualError) {
318
logger.error({
319
message: individualError.message,
320
stack: individualError.stack,
321
name: individualError.name
322
});
323
});
324
}
325
326
// Useful for collecting error details
327
function collectErrorMessages(err) {
328
const messages = [];
329
VError.errorForEach(err, function(individualError) {
330
messages.push(individualError.message);
331
});
332
return messages;
333
}
334
335
const multiError = new VError.MultiError([
336
new Error('error 1'),
337
new Error('error 2')
338
]);
339
console.log(collectErrorMessages(multiError)); // ['error 1', 'error 2']
340
```
341
342
### Utility Method Patterns
343
344
Common patterns for using the static utility methods together:
345
346
```javascript { .api }
347
/**
348
* Common utility patterns:
349
*
350
* Error Analysis: Use cause(), info(), findCauseByName() to analyze errors
351
* Error Reporting: Use fullStack() for detailed logging
352
* Multi-Error Handling: Use errorFromList(), errorForEach() for parallel operations
353
* Error Classification: Use hasCauseWithName() for conditional handling
354
*/
355
```
356
357
**Usage Examples:**
358
359
```javascript
360
const VError = require('verror');
361
362
// Comprehensive error analysis
363
function analyzeError(err) {
364
console.log('Error analysis:');
365
console.log('- Message:', err.message);
366
console.log('- Name:', err.name);
367
368
const cause = VError.cause(err);
369
if (cause) {
370
console.log('- Has cause:', cause.message);
371
}
372
373
const info = VError.info(err);
374
if (Object.keys(info).length > 0) {
375
console.log('- Info:', JSON.stringify(info, null, 2));
376
}
377
378
console.log('- Full stack:', VError.fullStack(err));
379
}
380
381
// Error handling middleware
382
function errorHandler(err) {
383
// Log all individual errors
384
VError.errorForEach(err, function(individualError) {
385
logger.error({
386
message: individualError.message,
387
stack: individualError.stack
388
});
389
});
390
391
// Check for specific error types
392
if (VError.hasCauseWithName(err, 'DatabaseError')) {
393
return { status: 503, message: 'Service temporarily unavailable' };
394
} else if (VError.hasCauseWithName(err, 'ValidationError')) {
395
return { status: 400, message: 'Invalid request data' };
396
} else {
397
return { status: 500, message: 'Internal server error' };
398
}
399
}
400
401
// Parallel operation error aggregation
402
async function processMultipleItems(items) {
403
const results = await Promise.allSettled(
404
items.map(item => processItem(item))
405
);
406
407
const errors = results
408
.filter(result => result.status === 'rejected')
409
.map(result => result.reason);
410
411
const aggregatedError = VError.errorFromList(errors);
412
if (aggregatedError) {
413
// Add context to the aggregated error
414
throw new VError(aggregatedError, 'failed to process %d items', items.length);
415
}
416
417
return results.map(result => result.value);
418
}
419
```