/* * verror.js: richer JavaScript errors */ var mod_assert = require('assert'); var mod_util = require('util'); var mod_extsprintf = require('extsprintf'); /* * Public interface */ exports.VError = VError; exports.WError = WError; exports.MultiError = MultiError; /* * Like JavaScript's built-in Error class, but supports a "cause" argument and a * printf-style message. The cause argument can be null. */ function VError(options) { var args, causedBy, ctor, tailmsg; if (options instanceof Error || typeof (options) === 'object') { args = Array.prototype.slice.call(arguments, 1); } else { args = Array.prototype.slice.call(arguments, 0); options = undefined; } tailmsg = args.length > 0 ? mod_extsprintf.sprintf.apply(null, args) : ''; this.jse_shortmsg = tailmsg; this.jse_summary = tailmsg; if (options) { causedBy = options.cause; if (!causedBy || !(options.cause instanceof Error)) causedBy = options; if (causedBy && (causedBy instanceof Error)) { this.jse_cause = causedBy; this.jse_summary += ': ' + causedBy.message; } } this.message = this.jse_summary; Error.call(this, this.jse_summary); if (Error.captureStackTrace) { ctor = options ? options.constructorOpt : undefined; ctor = ctor || arguments.callee; Error.captureStackTrace(this, ctor); } } mod_util.inherits(VError, Error); VError.prototype.name = 'VError'; VError.prototype.toString = function ve_toString() { var str = (this.hasOwnProperty('name') && this.name || this.constructor.name || this.constructor.prototype.name); if (this.message) str += ': ' + this.message; return (str); }; VError.prototype.cause = function ve_cause() { return (this.jse_cause); }; /* * Represents a collection of errors for the purpose of consumers that generally * only deal with one error. Callers can extract the individual errors * contained in this object, but may also just treat it as a normal single * error, in which case a summary message will be printed. */ function MultiError(errors) { mod_assert.ok(errors.length > 0); this.ase_errors = errors; VError.call(this, errors[0], 'first of %d error%s', errors.length, errors.length == 1 ? '' : 's'); } mod_util.inherits(MultiError, VError); /* * Like JavaScript's built-in Error class, but supports a "cause" argument which * is wrapped, not "folded in" as with VError. Accepts a printf-style message. * The cause argument can be null. */ function WError(options) { Error.call(this); var args, cause, ctor; if (typeof (options) === 'object') { args = Array.prototype.slice.call(arguments, 1); } else { args = Array.prototype.slice.call(arguments, 0); options = undefined; } if (args.length > 0) { this.message = mod_extsprintf.sprintf.apply(null, args); } else { this.message = ''; } if (options) { if (options instanceof Error) { cause = options; } else { cause = options.cause; ctor = options.constructorOpt; } } Error.captureStackTrace(this, ctor || this.constructor); if (cause) this.cause(cause); } mod_util.inherits(WError, Error); WError.prototype.name = 'WError'; WError.prototype.toString = function we_toString() { var str = (this.hasOwnProperty('name') && this.name || this.constructor.name || this.constructor.prototype.name); if (this.message) str += ': ' + this.message; if (this.we_cause && this.we_cause.message) str += '; caused by ' + this.we_cause.toString(); return (str); }; WError.prototype.cause = function we_cause(c) { if (c instanceof Error) this.we_cause = c; return (this.we_cause); };