var util = require('util'); var arrayDiffer = require('array-differ'); var arrayUniq = require('array-uniq'); var chalk = require('chalk'); var objectAssign = require('object-assign'); var nonEnumberableProperties = ['name', 'message', 'stack']; var propertiesNotToDisplay = nonEnumberableProperties.concat(['plugin', 'showStack', 'showProperties', '__safety', '_stack']); // wow what a clusterfuck var parseOptions = function(plugin, message, opt) { opt = opt || {}; if (typeof plugin === 'object') { opt = plugin; } else { if (message instanceof Error) { opt.error = message; } else if (typeof message === 'object') { opt = message; } else { opt.message = message; } opt.plugin = plugin; } return objectAssign({ showStack: false, showProperties: true }, opt); }; function PluginError(plugin, message, opt) { if (!(this instanceof PluginError)) throw new Error('Call PluginError using new'); Error.call(this); var options = parseOptions(plugin, message, opt); var self = this; // if options has an error, grab details from it if (options.error) { // These properties are not enumerable, so we have to add them explicitly. arrayUniq(Object.keys(options.error).concat(nonEnumberableProperties)) .forEach(function(prop) { self[prop] = options.error[prop]; }); } var properties = ['name', 'message', 'fileName', 'lineNumber', 'stack', 'showStack', 'showProperties', 'plugin']; // options object can override properties.forEach(function(prop) { if (prop in options) this[prop] = options[prop]; }, this); // defaults if (!this.name) this.name = 'Error'; if (!this.stack) { // Error.captureStackTrace appends a stack property which relies on the toString method of the object it is applied to. // Since we are using our own toString method which controls when to display the stack trace if we don't go through this // safety object, then we'll get stack overflow problems. var safety = { toString: function() { return this._messageWithDetails() + '\nStack:'; }.bind(this) }; Error.captureStackTrace(safety, arguments.callee || this.constructor); this.__safety = safety; } if (!this.plugin) throw new Error('Missing plugin name'); if (!this.message) throw new Error('Missing error message'); } util.inherits(PluginError, Error); PluginError.prototype._messageWithDetails = function() { var messageWithDetails = 'Message:\n ' + this.message; var details = this._messageDetails(); if (details !== '') { messageWithDetails += '\n' + details; } return messageWithDetails; }; PluginError.prototype._messageDetails = function() { if (!this.showProperties) { return ''; } var properties = arrayDiffer(Object.keys(this), propertiesNotToDisplay); if (properties.length === 0) { return ''; } var self = this; properties = properties.map(function stringifyProperty(prop) { return ' ' + prop + ': ' + self[prop]; }); return 'Details:\n' + properties.join('\n'); }; PluginError.prototype.toString = function () { var sig = chalk.red(this.name) + ' in plugin \'' + chalk.cyan(this.plugin) + '\''; var detailsWithStack = function(stack) { return this._messageWithDetails() + '\nStack:\n' + stack; }.bind(this); var msg; if (this.showStack) { if (this.__safety) { // There is no wrapped error, use the stack captured in the PluginError ctor msg = this.__safety.stack; } else if (this._stack) { msg = detailsWithStack(this._stack); } else { // Stack from wrapped error msg = detailsWithStack(this.stack); } } else { msg = this._messageWithDetails(); } return sig + '\n' + msg; }; module.exports = PluginError;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 19553 | swellard | Move and rename clients | ||
//guest/perforce_software/helix-web-services/main/source/clients/2016.1.0/javascript/node_modules/gulp-util/lib/PluginError.js | |||||
#1 | 18810 | tjuricek |
First-pass at JavaScript client SDK. JavaScript requires Node with Gulp to "browserfy" the library. It's the easiest way I found to use the swagger-js project; bundle up a wrapping method. There is no JavaScript reference guide. The swagger-js doesn't really document what they do very well, actually. Overall I'm not particularly impressed by swagger-js, it was hard to even figure out what the right method syntax was. We may want to invest time in doing it better. This required setting CORS response headers, which are currently defaulted to a fairly insecure setting. |