isaacs/npm — pull request #4373 by rlidwka (2013-12-24 03:08:43+00:00)
Title: make JSON.parse return error positions

See issue #3869. Since it is marked patch-welcome, here is a patch. :)

### Setup:

```
$ echo '{ "name": "test", some garbage' > package.json
```

### Was:

```
$ npm install
npm ERR! install Couldn't read dependencies
npm ERR! Failed to parse json
npm ERR! Unexpected token s
npm ERR! File: /tmp/package.json
npm ERR! Failed to parse package.json data.
npm ERR! package.json must be actual JSON, not just JavaScript.
```

### Will be:

```
$ ~/npm/cli.js install
npm ERR! install Couldn't read dependencies
npm ERR! Failed to parse json
npm ERR! Unexpected token 's' at 1:19
npm ERR! { "name": "test", some garbage
npm ERR! ^
npm ERR! File: /tmp/package.json
npm ERR! Failed to parse package.json data.
npm ERR! package.json must be actual JSON, not just JavaScript.
```

### Implementation:

It was suggested earlier to simply wrap JSON.parse in try..catch whereever it's used and use another library to figure out an exact error.

Sadly, it needs to be done for every JSON.parse call there is. Including those parsing npm-shrinkwrap.json and God knows what else. Ok, we can wrap it into it's own function.

Sadly, npm is scattered across multiple packages, so for example read-package-json will need to be updated as well. When I got to this point, I said "screw it, making minor pull requests to multiple packages is just stupid" and wrote a nice patch.

### Monkeypatch warning:

Yes, I perfectly understand the implications of it. Every single library including core will have this fallback. But since it's only a fallback, [what could possibly go wrong](https://en.wikipedia.org/wiki/Murphy%27s_law)?

### Disadvantages:

1. If the error is deep inside json, parser will bloat up your stack trace with internal calls. Probably fixable with another try..catch.
2. If somebody uses reviver (?) with side effects (??), it may be called x2 times. Maybe check for error type or something.

### Tests:

None at the moment, but I can add some upon request.