UNPKG

cordova-plugin-mfp-encrypt-utils

Version:

IBM MobileFirst Platform Foundation Cordova Plugin Encrypt Utils

251 lines (208 loc) 6.99 kB
/* * verror.js: richer JavaScript errors */ var mod_assert = require('assert'); var mod_util = require('util'); var mod_extsprintf = require('extsprintf'); var mod_isError = require('core-util-is').isError; /* * Public interface */ /* So you can 'var VError = require('verror')' */ module.exports = VError; /* For compatibility */ VError.VError = VError; /* Other exported classes */ VError.SError = SError; VError.WError = WError; VError.MultiError = MultiError; /* * VError([cause], fmt[, arg...]): Like JavaScript's built-in Error class, but * supports a "cause" argument (another error) and a printf-style message. The * cause argument can be null or omitted entirely. * * Examples: * * CODE MESSAGE * new VError('something bad happened') "something bad happened" * new VError('missing file: "%s"', file) "missing file: "/etc/passwd" * with file = '/etc/passwd' * new VError(err, 'open failed') "open failed: file not found" * with err.message = 'file not found' */ function VError(options) { var args, obj, causedBy, ctor, tailmsg; /* * This is a regrettable pattern, but JavaScript's built-in Error class * is defined to work this way, so we allow the constructor to be called * without "new". */ if (!(this instanceof VError)) { args = Array.prototype.slice.call(arguments, 0); obj = Object.create(VError.prototype); VError.apply(obj, arguments); return (obj); } if (mod_isError(options) || typeof (options) === 'object') { args = Array.prototype.slice.call(arguments, 1); } else { args = Array.prototype.slice.call(arguments, 0); options = undefined; } /* * extsprintf (which we invoke here with our caller's arguments in order * to construct this Error's message) is strict in its interpretation of * values to be processed by the "%s" specifier. The value passed to * extsprintf must actually be a string or something convertible to a * String using .toString(). Passing other values (notably "null" and * "undefined") is considered a programmer error. The assumption is * that if you actually want to print the string "null" or "undefined", * then that's easy to do that when you're calling extsprintf; on the * other hand, if you did NOT want that (i.e., there's actually a bug * where the program assumes some variable is non-null and tries to * print it, which might happen when constructing a packet or file in * some specific format), then it's better to stop immediately than * produce bogus output. * * However, sometimes the bug is only in the code calling VError, and a * programmer might prefer to have the error message contain "null" or * "undefined" rather than have the bug in the error path crash the * program (making the first bug harder to identify). For that reason, * by default VError converts "null" or "undefined" arguments to their * string representations and passes those to extsprintf. Programmers * desiring the strict behavior can use the SError class or pass the * "strict" option to the VError constructor. */ if (!options || !options.strict) { args = args.map(function (a) { return (a === null ? 'null' : a === undefined ? 'undefined' : a); }); } 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 || !mod_isError(options.cause)) causedBy = options; if (causedBy && mod_isError(causedBy)) { 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); } return (this); } 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); }; /* * SError is like VError, but stricter about types. You cannot pass "null" or * "undefined" as string arguments to the formatter. Since SError is only a * different function, not really a different class, we don't set * SError.prototype.name. */ function SError() { var fmtargs, opts, key, args; opts = {}; opts.constructorOpt = SError; if (mod_isError(arguments[0])) { opts.cause = arguments[0]; fmtargs = Array.prototype.slice.call(arguments, 1); } else if (typeof (arguments[0]) == 'object') { for (key in arguments[0]) opts[key] = arguments[0][key]; fmtargs = Array.prototype.slice.call(arguments, 1); } else { fmtargs = Array.prototype.slice.call(arguments, 0); } opts.strict = true; args = [ opts ].concat(fmtargs); VError.apply(this, args); } mod_util.inherits(SError, VError); /* * 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 (mod_isError(options)) { 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 (mod_isError(c)) this.we_cause = c; return (this.we_cause); };