pax_global_header00006660000000000000000000000064132317410560014514gustar00rootroot0000000000000052 comment=1d51476e4d7da44c1daea246531ae822617e4565 plugin-error-1.0.1/000077500000000000000000000000001323174105600141405ustar00rootroot00000000000000plugin-error-1.0.1/.editorconfig000066400000000000000000000003261323174105600166160ustar00rootroot00000000000000# http://editorconfig.org root = true [*] indent_style = space indent_size = 2 charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true end_of_line = lf [*.md] trim_trailing_whitespace = false plugin-error-1.0.1/.eslintrc000066400000000000000000000000301323174105600157550ustar00rootroot00000000000000{ "extends": "gulp" } plugin-error-1.0.1/.gitattributes000066400000000000000000000000161323174105600170300ustar00rootroot00000000000000* text eol=lf plugin-error-1.0.1/.gitignore000066400000000000000000000011461323174105600161320ustar00rootroot00000000000000# Logs logs *.log # Runtime data pids *.pid *.seed # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directory # Commenting this out is preferred by some people, see # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- node_modules # Users Environment Variables .lock-wscript # Garbage files .DS_Store plugin-error-1.0.1/.jscsrc000066400000000000000000000000271323174105600154270ustar00rootroot00000000000000{ "preset": "gulp" } plugin-error-1.0.1/.travis.yml000066400000000000000000000001711323174105600162500ustar00rootroot00000000000000sudo: false language: node_js node_js: - '8' - '6' - '4' - '0.12' - '0.10' after_script: - npm run coveralls plugin-error-1.0.1/LICENSE000066400000000000000000000022141323174105600151440ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2015 Blaine Bublitz , Eric Schoffstall and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. plugin-error-1.0.1/README.md000066400000000000000000000046151323174105600154250ustar00rootroot00000000000000

# plugin-error [![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![Gitter chat][gitter-image]][gitter-url] Error handling for Vinyl plugins. ## Usage ```js var PluginError = require('plugin-error'); var err = new PluginError('test', { message: 'something broke' }); var err = new PluginError({ plugin: 'test', message: 'something broke' }); var err = new PluginError('test', 'something broke'); var err = new PluginError('test', 'something broke', { showStack: true }); var existingError = new Error('OMG'); var err = new PluginError('test', existingError, { showStack: true }); ``` ## API ### `new PluginError(pluginName, message[, options])` Error constructor that takes: * `pluginName` - a `String` that should be the module name of your plugin * `message` - a `String` message or an existing `Error` object * `options` - an `Object` of your options **Behavior:** * By default the stack will not be shown. Set `options.showStack` to true if you think the stack is important for your error. * If you pass an error object as the message the stack will be pulled from that, otherwise one will be created. * If you pass in a custom stack string you need to include the message along with that. * Error properties will be included in `err.toString()`, but may be omitted by including `{ showProperties: false }` in the options. ## License MIT [downloads-image]: http://img.shields.io/npm/dm/plugin-error.svg [npm-url]: https://www.npmjs.com/package/plugin-error [npm-image]: http://img.shields.io/npm/v/plugin-error.svg [travis-url]: https://travis-ci.org/gulpjs/plugin-error [travis-image]: http://img.shields.io/travis/gulpjs/plugin-error.svg?label=travis-ci [appveyor-url]: https://ci.appveyor.com/project/gulpjs/plugin-error [appveyor-image]: https://img.shields.io/appveyor/ci/gulpjs/plugin-error.svg?label=appveyor [coveralls-url]: https://coveralls.io/r/gulpjs/plugin-error [coveralls-image]: http://img.shields.io/coveralls/gulpjs/plugin-error/master.svg [gitter-url]: https://gitter.im/gulpjs/gulp [gitter-image]: https://badges.gitter.im/gulpjs/gulp.svg plugin-error-1.0.1/appveyor.yml000066400000000000000000000007211323174105600165300ustar00rootroot00000000000000# http://www.appveyor.com/docs/appveyor-yml # http://www.appveyor.com/docs/lang/nodejs-iojs environment: matrix: # node.js - nodejs_version: "0.10" - nodejs_version: "0.12" - nodejs_version: "4" - nodejs_version: "6" - nodejs_version: "8" install: - ps: Install-Product node $env:nodejs_version - npm install test_script: - node --version - npm --version - cmd: npm test build: off # build version format version: "{build}" plugin-error-1.0.1/index.d.ts000066400000000000000000000052441323174105600160460ustar00rootroot00000000000000declare namespace PluginError { interface Constructor { /** * @param plugin Plugin name * @param error Base error * @param options Error options */ new (plugin: string, error: E, options?: Options): PluginError; /** * @param plugin Plugin name * @param error Base error or error message * @param options Error options */ new (plugin: string, error: E | string, options: Options): PluginError; /** * @param plugin Plugin name * @param error Base error, error message, or options with message */ new (plugin: string, error: E | string | (Options & {message: string})): PluginError; /** * @param options Options with plugin name and message */ new(options: Options & {plugin: string, message: string}): PluginError; } interface Options { /** * Error name */ name?: string; /** * Error message */ message?: any; /** * File name where the error occurred */ fileName?: string; /** * Line number where the error occurred */ lineNumber?: number; /** * Error properties will be included in err.toString(). Can be omitted by * setting this to false. * * Default: `true` */ showProperties?: boolean; /** * By default the stack will not be shown. Set this to true if you think the * stack is important for your error. * * Default: `false` */ showStack?: boolean; /** * Error stack to use for `err.toString()` if `showStack` is `true`. * By default it uses the `stack` of the original error if you used one, otherwise it captures a new stack. */ stack?: string; } /** * The `SimplePluginError` interface defines the properties available on all the the instances of `PluginError`. * * @internal */ interface SimplePluginError extends Error { /** * Plugin name */ plugin: string; /** * Boolean controlling if the stack will be shown in `err.toString()`. */ showStack: boolean; /** * Boolean controlling if properties will be shown in `err.toString()`. */ showProperties: boolean; /** * File name where the error occurred */ fileName?: string; /** * Line number where the error occurred */ lineNumber?: number; } } /** * Abstraction for error handling for Vinyl plugins */ type PluginError = PluginError.SimplePluginError & T; declare const PluginError: PluginError.Constructor; export = PluginError; plugin-error-1.0.1/index.js000066400000000000000000000103301323174105600156020ustar00rootroot00000000000000var util = require('util'); var colors = require('ansi-colors'); var extend = require('extend-shallow'); var differ = require('arr-diff'); var union = require('arr-union'); var nonEnum = ['message', 'name', 'stack']; var ignored = union(nonEnum, ['__safety', '_stack', 'plugin', 'showProperties', 'showStack']); var props = ['fileName', 'lineNumber', 'message', 'name', 'plugin', 'showProperties', 'showStack', 'stack']; function PluginError(plugin, message, options) { if (!(this instanceof PluginError)) { throw new Error('Call PluginError using new'); } Error.call(this); var opts = setDefaults(plugin, message, options); var self = this; // If opts has an error, get details from it if (typeof opts.error === 'object') { var keys = union(Object.keys(opts.error), nonEnum); // These properties are not enumerable, so we have to add them explicitly. keys.forEach(function(prop) { self[prop] = opts.error[prop]; }); } // Opts object can override props.forEach(function(prop) { if (prop in opts) { this[prop] = opts[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 we'll get stack overflow problems. */ var safety = {}; 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); /** * Output a formatted message with details */ PluginError.prototype._messageWithDetails = function() { var msg = 'Message:\n ' + this.message; var details = this._messageDetails(); if (details !== '') { msg += '\n' + details; } return msg; }; /** * Output actual message details */ PluginError.prototype._messageDetails = function() { if (!this.showProperties) { return ''; } var props = differ(Object.keys(this), ignored); var len = props.length; if (len === 0) { return ''; } var res = ''; var i = 0; while (len--) { var prop = props[i++]; res += ' '; res += prop + ': ' + this[prop]; res += '\n'; } return 'Details:\n' + res; }; /** * Override the `toString` method */ PluginError.prototype.toString = function() { var detailsWithStack = function(stack) { return this._messageWithDetails() + '\nStack:\n' + stack; }.bind(this); var msg = ''; if (this.showStack) { // If there is no wrapped error, use the stack captured in the PluginError ctor if (this.__safety) { msg = this.__safety.stack; } else if (this._stack) { msg = detailsWithStack(this._stack); } else { // Stack from wrapped error msg = detailsWithStack(this.stack); } return message(msg, this); } msg = this._messageWithDetails(); return message(msg, this); }; // Format the output message function message(msg, thisArg) { var sig = colors.red(thisArg.name); sig += ' in plugin '; sig += '"' + colors.cyan(thisArg.plugin) + '"'; sig += '\n'; sig += msg; return sig; } /** * Set default options based on arguments. */ function setDefaults(plugin, message, opts) { if (typeof plugin === 'object') { return defaults(plugin); } opts = opts || {}; if (message instanceof Error) { opts.error = message; } else if (typeof message === 'object') { opts = message; } else { opts.message = message; } opts.plugin = plugin; return defaults(opts); } /** * Extend default options with: * * - `showStack`: default=false * - `showProperties`: default=true * * @param {Object} `opts` Options to extend * @return {Object} */ function defaults(opts) { return extend({ showStack: false, showProperties: true, }, opts); } /** * Expose `PluginError` */ module.exports = PluginError; plugin-error-1.0.1/package.json000066400000000000000000000023661323174105600164350ustar00rootroot00000000000000{ "name": "plugin-error", "version": "1.0.1", "description": "Error handling for Vinyl plugins.", "author": "Gulp Team (http://gulpjs.com/)", "contributors": [ "Jon Schlinkert ", "Blaine Bublitz " ], "repository": "gulpjs/plugin-error", "license": "MIT", "engines": { "node": ">= 0.10" }, "main": "index.js", "files": [ "LICENSE", "index.d.ts", "index.js" ], "scripts": { "lint": "eslint . && jscs index.js test/", "pretest": "npm run lint", "test": "mocha --async-only && npm run test-types", "test-types": "tsc -p test/types", "cover": "istanbul cover _mocha --report lcovonly", "coveralls": "npm run cover && istanbul-coveralls" }, "dependencies": { "ansi-colors": "^1.0.1", "arr-diff": "^4.0.0", "arr-union": "^3.1.0", "extend-shallow": "^3.0.2" }, "devDependencies": { "eslint": "^1.7.3", "eslint-config-gulp": "^2.0.0", "expect": "^1.20.2", "istanbul": "^0.4.3", "istanbul-coveralls": "^1.0.3", "jscs": "^2.3.5", "jscs-preset-gulp": "^1.0.0", "mocha": "^3.0.0", "typescript": "^2.6.2" }, "keywords": [ "error", "plugin", "gulp-util" ] } plugin-error-1.0.1/test/000077500000000000000000000000001323174105600151175ustar00rootroot00000000000000plugin-error-1.0.1/test/.eslintrc000066400000000000000000000000351323174105600167410ustar00rootroot00000000000000{ "extends": "gulp/test" } plugin-error-1.0.1/test/index.js000066400000000000000000000167441323174105600166000ustar00rootroot00000000000000'use strict'; var expect = require('expect'); var PluginError = require('../'); describe('PluginError()', function() { it('should default name to Error', function(done) { var err = new PluginError('test', 'something broke'); expect(err.name).toEqual('Error'); done(); }); it('should default name to Error, even when wrapped error has no name', function(done) { var realErr = { message: 'something broke' }; var err = new PluginError('test', realErr); expect(err.name).toEqual('Error'); done(); }); it('should print the plugin name in toString', function(done) { var err = new PluginError('test', 'something broke'); expect(err.toString()).toContain('test'); done(); }); it('should not include the stack by default in toString', function(done) { var err = new PluginError('test', 'something broke'); // Just check that there are no 'at' lines expect(err.toString()).toNotContain('at'); done(); }); it('should include the stack when specified in toString', function(done) { var err = new PluginError('test', 'something broke', { stack: 'at huh', showStack: true }); // Just check that there are 'at' lines expect(err.toString()).toContain('at'); done(); }); it('should take arguments as one object', function(done) { var err = new PluginError({ plugin: 'test', message: 'something broke', }); expect(err.plugin).toEqual('test'); expect(err.message).toEqual('something broke'); done(); }); it('should take arguments as plugin name and one object', function(done) { var err = new PluginError('test', { message: 'something broke', }); expect(err.plugin).toEqual('test'); expect(err.message).toEqual('something broke'); done(); }); it('should take arguments as plugin name and message', function(done) { var err = new PluginError('test', 'something broke'); expect(err.plugin).toEqual('test'); expect(err.message).toEqual('something broke'); done(); }); it('should take arguments as plugin name, message, and one object', function(done) { var err = new PluginError('test', 'something broke', { showStack: true }); expect(err.plugin).toEqual('test'); expect(err.message).toEqual('something broke'); expect(err.showStack).toEqual(true); done(); }); it('should take arguments as plugin name, error, and one object', function(done) { var realErr = new Error('something broke'); realErr.fileName = 'original.js'; var err = new PluginError('test', realErr, { showStack: true, fileName: 'override.js' }); expect(err.plugin).toEqual('test'); expect(err.message).toEqual('something broke'); expect(err.fileName).toEqual('override.js'); expect(err.showStack).toEqual(true); done(); }); it('should take properties from error', function(done) { var realErr = new Error('something broke'); realErr.abstractProperty = 'abstract'; var err = new PluginError('test', realErr); expect(err.plugin).toEqual('test'); expect(err.message).toEqual('something broke'); expect(err.abstractProperty).toEqual('abstract'); done(); }); it('should be configured to show properties by default', function(done) { var err = new PluginError('test', 'something broke'); expect(err.showProperties).toBe(true); done(); }); it('should not be configured to take option to show properties', function(done) { var err = new PluginError('test', 'something broke', { showProperties: false }); expect(err.showProperties).toBe(false); done(); }); it('should show properties', function(done) { var err = new PluginError('test', 'it broke', { showProperties: true }); err.fileName = 'original.js'; err.lineNumber = 35; expect(err.toString()).toContain('it broke'); expect(err.toString()).toNotContain('message:'); expect(err.toString()).toContain('fileName:'); done(); }); it('should show properties', function(done) { var realErr = new Error('something broke'); realErr.fileName = 'original.js'; realErr.lineNumber = 35; var err = new PluginError('test', realErr, { showProperties: true }); expect(err.toString()).toNotContain('message:'); expect(err.toString()).toContain('fileName:'); done(); }); it('should not show properties', function(done) { var realErr = new Error('something broke'); realErr.fileName = 'original.js'; realErr.lineNumber = 35; var err = new PluginError('test', realErr, { showProperties: false }); expect(err.toString()).toNotContain('message:'); expect(err.toString()).toNotContain('fileName:'); done(); }); it('should not show properties, but should show stack', function(done) { var err = new PluginError('test', 'it broke', { stack: 'test stack', showStack: true, showProperties: false }); err.fileName = 'original.js'; err.lineNumber = 35; expect(err.toString()).toNotContain('message:'); expect(err.toString()).toNotContain('fileName:'); expect(err.toString()).toContain('test stack'); done(); }); it('should not show properties, but should show stack for real error', function(done) { var realErr = new Error('something broke'); realErr.fileName = 'original.js'; realErr.lineNumber = 35; realErr.stack = 'test stack'; var err = new PluginError('test', realErr, { showStack: true, showProperties: false }); expect(err.toString().indexOf('message:')).toEqual(-1); expect(err.toString().indexOf('fileName:')).toEqual(-1); expect(err.toString().indexOf('test stack')).toNotEqual(-1); done(); }); it('should not show properties, but should show stack for _stack', function(done) { var realErr = new Error('something broke'); realErr.fileName = 'original.js'; realErr.lineNumber = 35; realErr._stack = 'test stack'; var err = new PluginError('test', realErr, { showStack: true, showProperties: false }); expect(err.toString().indexOf('message:')).toEqual(-1); expect(err.toString().indexOf('fileName:')).toEqual(-1); expect(err.toString().indexOf('test stack')).toNotEqual(-1); done(); }); it('should show properties and stack', function(done) { var realErr = new Error('something broke'); realErr.fileName = 'original.js'; realErr.stack = 'test stack'; var err = new PluginError('test', realErr, { showStack: true }); expect(err.toString().indexOf('message:')).toEqual(-1); expect(err.toString().indexOf('fileName:')).toNotEqual(-1); expect(err.toString().indexOf('test stack')).toNotEqual(-1); done(); }); it('should show properties added after the error is created', function(done) { var realErr = new Error('something broke'); var err = new PluginError('test', realErr); err.fileName = 'original.js'; expect(err.toString().indexOf('message:')).toEqual(-1); expect(err.toString().indexOf('fileName:')).toNotEqual(-1); done(); }); it('should toString quickly', function(done) { this.timeout(100); var err = new PluginError('test', 'it broke', { showStack: true }); err.toString(); done(); }); it('should toString quickly with original error', function(done) { this.timeout(100); var realErr = new Error('it broke'); var err = new PluginError('test', realErr, { showStack: true }); err.toString(); done(); }); it('should not show "Details:" if there are no properties to show', function(done) { var err = new PluginError('plugin', 'message'); expect(err.toString().indexOf('Details:')).toEqual(-1); done(); }); }); plugin-error-1.0.1/test/types/000077500000000000000000000000001323174105600162635ustar00rootroot00000000000000plugin-error-1.0.1/test/types/test.ts000066400000000000000000000105241323174105600176140ustar00rootroot00000000000000import PluginError = require("plugin-error"); { // Check constructor signatures // See: https://github.com/gulpjs/gulp-util#new-pluginerrorpluginname-message-options { const err = new PluginError("test", { message: "something broke", }); } { const err = new PluginError({ plugin: "test", message: "something broke", }); } { const err = new PluginError("test", "something broke"); } { const err = new PluginError("test", "something broke", {showStack: true}); } { const existingError = new Error("OMG"); const options: PluginError.Options = {showStack: true}; const err = new PluginError("test", existingError, options); } } { { // Check available properties const realErr = Object.assign(new Error("something broke"), {fileName: "original.js"}); const err = new PluginError("test", realErr, {showStack: true, fileName: "override.js"}); const plugin: string = err.plugin; const message: string = err.message; const fileName: string = err.fileName; const showStack: boolean = err.showStack; const showProperties: boolean = err.showProperties; } { // Inference of custom properties from `error` argument, const realErr = Object.assign(new Error("something broke"), {abstractProperty: "abstract"}); const err = new PluginError("test", realErr, realErr); const plugin: string = err.plugin; const message: string = err.message; const abstractProperty: string = err.abstractProperty; } } { // Union types const PLUGIN_NAME: string = "test"; interface FooError extends Error { foo: number; } const ERROR: Error = new Error("something broke"); const FOO_ERROR: FooError = Object.assign(new Error("something broke"), {foo: 1}); const MESSAGE: string = "something broke"; const OPTIONS: {message: string} = {message: "something broke"}; { function createError(error: Error | string) { return new PluginError(PLUGIN_NAME, error); } const pluginError1 = createError(ERROR); const pluginError2 = createError(FOO_ERROR); const pluginError3 = createError(MESSAGE); // The following code should cause a compilation error: // const foo: any = pluginError2.foo; } { // Make sure that custom properties are preserved function createError(error: FooError) { return new PluginError(PLUGIN_NAME, error); } const pluginError = createError(FOO_ERROR); const foo: number = pluginError.foo; } { // Just check that there's no issue when building it with a string function createError(error: string) { return new PluginError(PLUGIN_NAME, error); } const pluginError = createError(MESSAGE); // The following code should cause a compilation error: // const foo: any = pluginError.foo; } { // Check that custom properties are preserved but marked as potentially missing // The `foo` property must be of type `number | undefined` because it's existence depends // on the way `createError` is called. function createError(error: FooError | string) { return new PluginError(PLUGIN_NAME, error); } const pluginError1 = createError(FOO_ERROR); const foo1: number | undefined = pluginError1.foo; // The following code should cause a compilation error: // const foo2: number = pluginError1.foo; const pluginError2 = createError(MESSAGE); const foo3: number | undefined = pluginError2.foo; // The following code should cause a compilation error: // const foo4: number = pluginError2.foo; } { // Check support for unions with option object function createError(error: FooError | string | (PluginError.Options & {message: string})) { return new PluginError(PLUGIN_NAME, error); } const pluginError1 = createError(FOO_ERROR); const foo1: number | undefined = pluginError1.foo; // The following code should cause a compilation error: // const foo2: number = pluginError1.foo; const pluginError2 = createError(MESSAGE); const foo3: number | undefined = pluginError2.foo; // The following code should cause a compilation error: // const foo4: number = pluginError2.foo; const pluginError3 = createError(OPTIONS); const foo5: number | undefined = pluginError3.foo; // The following code should cause a compilation error: // const foo6: number = pluginError3.foo; } } plugin-error-1.0.1/test/types/tsconfig.json000066400000000000000000000030321323174105600207700ustar00rootroot00000000000000{ "compilerOptions": { "allowJs": false, "allowSyntheticDefaultImports": false, "allowUnreachableCode": false, "allowUnusedLabels": false, "alwaysStrict": true, "baseUrl": "../..", "charset": "utf8", "checkJs": false, "declaration": true, "disableSizeLimit": false, "downlevelIteration": false, "emitBOM": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, "forceConsistentCasingInFileNames": true, "importHelpers": false, "inlineSourceMap": false, "inlineSources": false, "isolatedModules": false, "lib": [ "es2017" ], "locale": "en-us", "module": "commonjs", "moduleResolution": "node", "newLine": "lf", "noEmit": true, "noEmitHelpers": false, "noEmitOnError": true, "noErrorTruncation": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": true, "noImplicitReturns": true, "noImplicitThis": true, "noStrictGenericChecks": false, "noUnusedLocals": false, "noUnusedParameters": false, "noLib": false, "noResolve": false, "paths": { "plugin-error": [ "index.d.ts" ] }, "preserveConstEnums": true, "removeComments": false, "rootDir": "", "skipLibCheck": false, "sourceMap": true, "strict": true, "strictNullChecks": true, "suppressExcessPropertyErrors": false, "suppressImplicitAnyIndexErrors": false, "target": "es2017", "traceResolution": false }, "include": [ "./**/*.ts" ], "exclude": [] }