Repository: lirantal/lockfile-lint
Pull request #13 (2019-10-12 22:48:33)

#9 More verbose error messages: include package name 
<!--- Provide a general summary of your changes in the Title above -->

## Description

Provide more verbose information - which includes the package name - on errors encountered during validation. In order to solve this I created a custom error type called `PackageError` which prints out the package name as well as the original error message and stacktrace. It is used in validators.

## Types of changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Related Issue

#9 

## Motivation and Context

More informative error message.

## How Has This Been Tested?

Added a test-case for each validator. Based on mocked packages containing a bad url these test cases assert that `PackageError` was thrown.

## Screenshots (if appropriate):
Example output:
```
$ lockfile-lint -p bad-yarn.lock --allowed-hosts yarn --validate-https -t yarn
ABORTING lockfile lint process due to error exceptions 

Encountered error Invalid URL: /registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791 in package: "debug@^4.1.1" 

TypeError [ERR_INVALID_URL]: Invalid URL: /registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791
    at onParseError (internal/url.js:241:17)
    at new URL (internal/url.js:319:5)
    at ValidateHost.validate ...

error: command failed with exit code 1
```

## Checklist:

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [x] I have updated the documentation (if required).
- [x] I have read the **CONTRIBUTING** document.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.
- [x] I added a picture of a cute animal cause it's fun

![cat](https://user-images.githubusercontent.com/5598081/66708595-642d2d80-ed5b-11e9-9f1f-3ea99d23de2e.gif)



codecov-io: # [Codecov](https://codecov.io/gh/lirantal/lockfile-lint/pull/13?src=pr&el=h1) Report
> Merging [#13](https://codecov.io/gh/lirantal/lockfile-lint/pull/13?src=pr&el=desc) into [master](https://codecov.io/gh/lirantal/lockfile-lint/commit/76a5b3c6b5342d71def53d1b9545e46496330bf0?src=pr&el=desc) will **increase** coverage by `0.48%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/lirantal/lockfile-lint/pull/13/graphs/tree.svg?width=650&token=P36VJa7ksa&height=150&src=pr)](https://codecov.io/gh/lirantal/lockfile-lint/pull/13?src=pr&el=tree)

```diff
@@            Coverage Diff            @@
##           master     #13      +/-   ##
=========================================
+ Coverage   95.62%   96.1%   +0.48%     
=========================================
  Files           8       9       +1     
  Lines         137     154      +17     
  Branches       20      21       +1     
=========================================
+ Hits          131     148      +17     
  Misses          6       6
```


| [Impacted Files](https://codecov.io/gh/lirantal/lockfile-lint/pull/13?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [...kages/lockfile-lint-api/src/common/PackageError.js](https://codecov.io/gh/lirantal/lockfile-lint/pull/13/diff?src=pr&el=tree#diff-cGFja2FnZXMvbG9ja2ZpbGUtbGludC1hcGkvc3JjL2NvbW1vbi9QYWNrYWdlRXJyb3IuanM=) | `100% <100%> (ø)` | |
| [.../lockfile-lint-api/src/validators/ValidateHttps.js](https://codecov.io/gh/lirantal/lockfile-lint/pull/13/diff?src=pr&el=tree#diff-cGFja2FnZXMvbG9ja2ZpbGUtbGludC1hcGkvc3JjL3ZhbGlkYXRvcnMvVmFsaWRhdGVIdHRwcy5qcw==) | `100% <100%> (ø)` | :arrow_up: |
| [...lockfile-lint-api/src/validators/ValidateScheme.js](https://codecov.io/gh/lirantal/lockfile-lint/pull/13/diff?src=pr&el=tree#diff-cGFja2FnZXMvbG9ja2ZpbGUtbGludC1hcGkvc3JjL3ZhbGlkYXRvcnMvVmFsaWRhdGVTY2hlbWUuanM=) | `94.73% <100%> (+1.4%)` | :arrow_up: |
| [...s/lockfile-lint-api/src/validators/ValidateHost.js](https://codecov.io/gh/lirantal/lockfile-lint/pull/13/diff?src=pr&el=tree#diff-cGFja2FnZXMvbG9ja2ZpbGUtbGludC1hcGkvc3JjL3ZhbGlkYXRvcnMvVmFsaWRhdGVIb3N0Lmpz) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/lirantal/lockfile-lint/pull/13?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/lirantal/lockfile-lint/pull/13?src=pr&el=footer). Last update [76a5b3c...ffd5291](https://codecov.io/gh/lirantal/lockfile-lint/pull/13?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/packages/lockfile-lint-api/CHANGELOG.md b/packages/lockfile-lint-api/CHANGELOG.md
index 500ea2d..6b80b00 100644
--- a/packages/lockfile-lint-api/CHANGELOG.md
+++ b/packages/lockfile-lint-api/CHANGELOG.md
@@ -3,6 +3,17 @@
 All notable changes to this project will be documented in this file.
 See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
 
+## [2.1.2](https://github.com/lirantal/lockfile-lint/compare/lockfile-lint-api@2.1.1...lockfile-lint-api@2.1.2) (2019-10-13)
+
+
+### Bug Fixes
+
+* **package:** remove tests and other files from published package ([#15](https://github.com/lirantal/lockfile-lint/issues/15)) ([1e61938](https://github.com/lirantal/lockfile-lint/commit/1e61938))
+
+
+
+
+
 ## [2.1.1](https://github.com/lirantal/lockfile-lint/compare/lockfile-lint-api@2.1.0...lockfile-lint-api@2.1.1) (2019-10-12)
 
 
diff --git a/packages/lockfile-lint-api/package.json b/packages/lockfile-lint-api/package.json
index c6d9e8a..804ca0d 100644
--- a/packages/lockfile-lint-api/package.json
+++ b/packages/lockfile-lint-api/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lockfile-lint-api",
-  "version": "2.1.1",
+  "version": "2.1.2",
   "description": "Lint an npm or yarn lockfile to analyze and detect issues",
   "main": "index.js",
   "engines": {
@@ -25,10 +25,8 @@
     "url": "https://github.com/lirantal"
   },
   "files": [
-    "*.js",
-    "src/**",
-    "__tests__/**",
-    "jsdoc.json"
+    "index.js",
+    "src/**/*.js"
   ],
   "license": "Apache-2.0",
   "keywords": [
diff --git a/packages/lockfile-lint-api/src/common/PackageError.js b/packages/lockfile-lint-api/src/common/PackageError.js
new file mode 100644
index 0000000..04fefa1
--- /dev/null
+++ b/packages/lockfile-lint-api/src/common/PackageError.js
@@ -0,0 +1,15 @@
+'use strict'
+
+module.exports = class PackageError extends Error {
+  /**
+   * constructor
+   * @param {string} packageName - the name of the package where the error occured
+   * @param {string} error - the original error object
+   */
+  constructor (packageName = '', error = {}) {
+    super()
+    this.name = error.name || 'Error'
+    this.message = `Encountered error ${error.message} in package: "${packageName}"`
+    this.stack = error.stack
+  }
+}
diff --git a/packages/lockfile-lint-api/src/validators/ValidateHost.js b/packages/lockfile-lint-api/src/validators/ValidateHost.js
index c10517e..ae80d55 100644
--- a/packages/lockfile-lint-api/src/validators/ValidateHost.js
+++ b/packages/lockfile-lint-api/src/validators/ValidateHost.js
@@ -1,6 +1,7 @@
 'use strict'
 
 const {URL} = require('url')
+const PackageError = require('../common/PackageError')
 
 const REGISTRY = {
   npm: 'registry.npmjs.org',
@@ -28,7 +29,12 @@ module.exports = class ValidateHost {
     }
 
     for (const [packageName, packageMetadata] of Object.entries(this.packages)) {
-      const packageResolvedURL = new URL(packageMetadata.resolved)
+      let packageResolvedURL = {}
+      try {
+        packageResolvedURL = new URL(packageMetadata.resolved)
+      } catch (error) {
+        throw new PackageError(packageName, error)
+      }
 
       const allowedHosts = hosts.map(hostValue => {
         // eslint-disable-next-line security/detect-object-injection
diff --git a/packages/lockfile-lint-api/src/validators/ValidateHttps.js b/packages/lockfile-lint-api/src/validators/ValidateHttps.js
index 1efd3f5..16fd5f1 100644
--- a/packages/lockfile-lint-api/src/validators/ValidateHttps.js
+++ b/packages/lockfile-lint-api/src/validators/ValidateHttps.js
@@ -1,6 +1,7 @@
 'use strict'
 
 const {URL} = require('url')
+const PackageError = require('../common/PackageError')
 
 const HTTPS_PROTOCOL = 'https:'
 
@@ -20,7 +21,12 @@ module.exports = class ValidateHttps {
     }
 
     for (const [packageName, packageMetadata] of Object.entries(this.packages)) {
-      const packageResolvedURL = new URL(packageMetadata.resolved)
+      let packageResolvedURL = {}
+      try {
+        packageResolvedURL = new URL(packageMetadata.resolved)
+      } catch (error) {
+        throw new PackageError(packageName, error)
+      }
 
       if (packageResolvedURL.protocol !== HTTPS_PROTOCOL) {
         validationResult.errors.push({
diff --git a/packages/lockfile-lint-api/src/validators/ValidateScheme.js b/packages/lockfile-lint-api/src/validators/ValidateScheme.js
index 8edc3cf..ab0d4dc 100644
--- a/packages/lockfile-lint-api/src/validators/ValidateScheme.js
+++ b/packages/lockfile-lint-api/src/validators/ValidateScheme.js
@@ -1,6 +1,7 @@
 'use strict'
 
 const {URL} = require('url')
+const PackageError = require('../common/PackageError')
 
 module.exports = class ValidateProtocol {
   constructor ({packages} = {}) {
@@ -22,7 +23,13 @@ module.exports = class ValidateProtocol {
     }
 
     for (const [packageName, packageMetadata] of Object.entries(this.packages)) {
-      const packageResolvedURL = new URL(packageMetadata.resolved)
+      let packageResolvedURL = {}
+      try {
+        packageResolvedURL = new URL(packageMetadata.resolved)
+      } catch (error) {
+        throw new PackageError(packageName, error)
+      }
+
       if (schemes.indexOf(packageResolvedURL.protocol) === -1) {
         // throw new Error(`detected invalid origin for package: ${packageName}`)
         validationResult.errors.push({
diff --git a/packages/lockfile-lint/CHANGELOG.md b/packages/lockfile-lint/CHANGELOG.md
index fa24492..f59d646 100644
--- a/packages/lockfile-lint/CHANGELOG.md
+++ b/packages/lockfile-lint/CHANGELOG.md
@@ -3,6 +3,17 @@
 All notable changes to this project will be documented in this file.
 See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
 
+## [2.1.3](https://github.com/lirantal/lockfile-lint/compare/lockfile-lint@2.1.2...lockfile-lint@2.1.3) (2019-10-13)
+
+
+### Bug Fixes
+
+* **package:** remove tests and other files from published package ([#15](https://github.com/lirantal/lockfile-lint/issues/15)) ([1e61938](https://github.com/lirantal/lockfile-lint/commit/1e61938))
+
+
+
+
+
 ## [2.1.2](https://github.com/lirantal/lockfile-lint/compare/lockfile-lint@2.1.1...lockfile-lint@2.1.2) (2019-10-12)
 
 **Note:** Version bump only for package lockfile-lint
diff --git a/packages/lockfile-lint/bin/lockfile-lint.js b/packages/lockfile-lint/bin/lockfile-lint.js
index e79703a..d1caaa6 100755
--- a/packages/lockfile-lint/bin/lockfile-lint.js
+++ b/packages/lockfile-lint/bin/lockfile-lint.js
@@ -31,9 +31,9 @@ try {
     validators
   })
 } catch (error) {
-  console.error('ABORTING lockfile lint process due to error exceptions')
-  console.error(error.message)
-  console.error(error.stack)
+  console.error('ABORTING lockfile lint process due to error exceptions', '\n')
+  console.error(error.message, '\n')
+  console.error(error.stack, '\n')
   console.error('error: command failed with exit code 1')
   process.exit(1)
 }
diff --git a/packages/lockfile-lint/package.json b/packages/lockfile-lint/package.json
index 72c93fd..ee2f5b0 100644
--- a/packages/lockfile-lint/package.json
+++ b/packages/lockfile-lint/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lockfile-lint",
-  "version": "2.1.2",
+  "version": "2.1.3",
   "description": "A CLI to lint a lockfile for security policies",
   "bin": {
     "lockfile-lint": "./bin/lockfile-lint.js"
@@ -27,11 +27,8 @@
     "url": "https://github.com/lirantal"
   },
   "files": [
-    "*.js",
-    "bin/**",
-    "src/**",
-    "__tests__/**",
-    "jsdoc.json"
+    "bin/*.js",
+    "src/**/*.js"
   ],
   "license": "Apache-2.0",
   "keywords": [
@@ -56,7 +53,7 @@
   },
   "dependencies": {
     "debug": "^4.1.0",
-    "lockfile-lint-api": "^2.1.1",
+    "lockfile-lint-api": "^2.1.2",
     "yargs": "^13.2.4"
   },
   "devDependencies": {


Test patch:
diff --git a/packages/lockfile-lint-api/__tests__/validators.host.test.js b/packages/lockfile-lint-api/__tests__/validators.host.test.js
index 5c96bb9..dbfc45c 100644
--- a/packages/lockfile-lint-api/__tests__/validators.host.test.js
+++ b/packages/lockfile-lint-api/__tests__/validators.host.test.js
@@ -1,4 +1,5 @@
 const ValidatorHost = require('../src/validators/ValidateHost')
+const PackageError = require('../src/common/PackageError')
 
 describe('Validator: Host', () => {
   it('validator should throw an error when provided a string', () => {
@@ -142,4 +143,15 @@ describe('Validator: Host', () => {
       ]
     })
   })
+
+  it('validator should throw a descriptive error when one is encounterd in a package', () => {
+    const mockedPackages = {
+      '@babel/code-frame': {
+        resolved: 'debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791'
+      }
+    }
+    const validator = new ValidatorHost({packages: mockedPackages})
+
+    expect(() => validator.validate(['npm'])).toThrow(PackageError)
+  })
 })
diff --git a/packages/lockfile-lint-api/__tests__/validators.https.test.js b/packages/lockfile-lint-api/__tests__/validators.https.test.js
index 57dbaf7..2f4dab6 100644
--- a/packages/lockfile-lint-api/__tests__/validators.https.test.js
+++ b/packages/lockfile-lint-api/__tests__/validators.https.test.js
@@ -1,4 +1,5 @@
 const ValidatorHTTPS = require('../src/validators/ValidateHttps')
+const PackageError = require('../src/common/PackageError')
 
 describe('Validator: HTTPS', () => {
   it('validator should throw an error when provided a string', () => {
@@ -58,4 +59,15 @@ describe('Validator: HTTPS', () => {
       errors: []
     })
   })
+
+  it('validator should throw a descriptive error when one is encounterd in a package', () => {
+    const mockedPackages = {
+      '@babel/code-frame': {
+        resolved: 'debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791'
+      }
+    }
+    const validator = new ValidatorHTTPS({packages: mockedPackages})
+
+    expect(() => validator.validate(['npm'])).toThrow(PackageError)
+  })
 })
diff --git a/packages/lockfile-lint-api/__tests__/validators.scheme.test.js b/packages/lockfile-lint-api/__tests__/validators.scheme.test.js
index 94c16c9..14e6dd2 100644
--- a/packages/lockfile-lint-api/__tests__/validators.scheme.test.js
+++ b/packages/lockfile-lint-api/__tests__/validators.scheme.test.js
@@ -1,4 +1,5 @@
 const ValidatorScheme = require('../src/validators/ValidateScheme')
+const PackageError = require('../src/common/PackageError')
 
 describe('Validator: Protocol', () => {
   it('validator should throw an error when provided a string', () => {
@@ -58,4 +59,15 @@ describe('Validator: Protocol', () => {
       errors: []
     })
   })
+
+  it('validator should throw a descriptive error when one is encounterd in a package', () => {
+    const mockedPackages = {
+      '@babel/code-frame': {
+        resolved: 'debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791'
+      }
+    }
+    const validator = new ValidatorScheme({packages: mockedPackages})
+
+    expect(() => validator.validate(['npm'])).toThrow(PackageError)
+  })
 })