Rich JavaScript errors with printf-style messages, error chaining, and structured metadata
—
The VError class is the primary error class that chains errors while preserving each error's message. It supports printf-style formatting, flexible constructor options, and provides a foundation for all other error classes in the library.
Creates a VError instance with flexible argument patterns supporting different use cases.
/**
* VError constructor with multiple signatures
* Can be called with or without 'new' keyword
*/
// Empty error
new VError();
// Printf-style message
new VError(message, ...printfArgs);
// Error with cause
new VError(causeError, message, ...printfArgs);
// Error with options
new VError(options, message, ...printfArgs);
/**
* Constructor options object
*/
interface VErrorOptions {
cause?: Error; // Underlying cause error
name?: string; // Error name override (default: 'VError')
info?: Object; // Additional structured metadata
skipCauseMessage?: boolean; // Skip appending cause message to this.message
strict?: boolean; // Force strict printf interpretation (like SError)
constructorOpt?: Function; // Constructor function for stack trace capture
}Usage Examples:
const VError = require('verror');
// Basic error
const err1 = new VError('something went wrong');
// Printf-style formatting
const err2 = new VError('failed to process file "%s"', filename);
// Error chaining
const err3 = new VError(originalError, 'operation failed');
// Full options
const err4 = new VError({
name: 'DatabaseError',
cause: dbError,
info: {
query: 'SELECT * FROM users',
table: 'users',
operation: 'select'
}
}, 'database query failed');
// Skip cause message in final message
const err5 = new VError({
cause: originalError,
skipCauseMessage: true
}, 'high-level operation failed');Properties available on VError instances for accessing error information.
interface VErrorInstance {
/** Error name, defaults to 'VError' or can be set via options */
name: string;
/** Complete error message including appended cause messages */
message: string;
/** Original short message without any cause messages appended */
jse_shortmsg: string;
/** Reference to the cause error, if provided */
jse_cause?: Error;
/** Additional information properties, shallow copy of options.info */
jse_info: Object;
/** Stack trace string */
stack: string;
}Methods available on VError instances.
/**
* Returns string representation of the error
* Format: "ErrorName: message"
* @returns {string} Formatted error string
*/
toString(): string;
/**
* Returns the cause error (compatibility method)
* NOTE: Returns undefined for no cause (use VError.cause() static method for null)
* @returns {Error|undefined} Cause error or undefined
*/
cause(): Error | undefined;Usage Examples:
const err = new VError({
name: 'ValidationError',
cause: originalError,
info: { field: 'email', value: 'invalid-email' }
}, 'validation failed for field "%s"', 'email');
console.log(err.name); // 'ValidationError'
console.log(err.message); // 'validation failed for field "email": original error message'
console.log(err.jse_shortmsg); // 'validation failed for field "email"'
console.log(err.jse_info); // { field: 'email', value: 'invalid-email' }
console.log(err.toString()); // 'ValidationError: validation failed for field "email": original error message'
console.log(err.cause()); // originalError instanceVError uses the extsprintf library for printf-style message formatting with special handling for null and undefined values.
/**
* Printf-style formatting behavior:
* - %s: string formatting
* - %d: decimal number formatting
* - %j: JSON formatting
* - null/undefined: converted to "null"/"undefined" strings (non-strict mode)
* - strict option: forces strict interpretation, throws on null/undefined
*/Usage Examples:
// Basic formatting
new VError('user %s not found', userId);
new VError('invalid count: %d', count);
new VError('data: %j', { key: 'value' });
// Null/undefined handling (VError converts them by default)
new VError('value is %s', null); // "value is null"
new VError('value is %s', undefined); // "value is undefined"
// Strict mode throws on null/undefined
new VError({ strict: true }, 'user %s', 'john'); // OK
// new VError({ strict: true }, 'value is %s', null); // Throws error
// Multiple arguments
new VError('error in %s at line %d: %s', filename, lineNumber, details);How VError constructs the final error message from components.
/**
* Message construction logic:
* 1. Format printf-style arguments into shortmessage
* 2. If cause exists and skipCauseMessage is false: shortmessage + ": " + cause.message
* 3. If cause exists and skipCauseMessage is true: shortmessage only
* 4. Final message is stored in this.message
*/Usage Examples:
const originalError = new Error('file not found');
// With cause message (default)
const err1 = new VError(originalError, 'failed to read config');
console.log(err1.message); // "failed to read config: file not found"
// Skip cause message
const err2 = new VError({
cause: originalError,
skipCauseMessage: true
}, 'failed to read config');
console.log(err2.message); // "failed to read config"
// Strict printf interpretation (like SError)
const err3 = new VError({ strict: true }, 'user %s not found', 'john'); // OK
// const err4 = new VError({ strict: true }, 'value is %s', null); // Would throw errorVError properly inherits from Error and can be extended.
/**
* VError inheritance:
* - Inherits from Error using util.inherits()
* - Can be called without 'new' keyword
* - Supports Error.captureStackTrace when available
* - Can be subclassed for custom error types
*/Usage Examples:
const util = require('util');
// Can be called without 'new'
const err1 = VError('without new keyword');
// Custom error class
function CustomError() {
VError.apply(this, arguments);
}
util.inherits(CustomError, VError);
CustomError.prototype.name = 'CustomError';
const customErr = new CustomError('custom error occurred');
console.log(customErr instanceof VError); // true
console.log(customErr instanceof Error); // trueInstall with Tessl CLI
npx tessl i tessl/npm-verror