From 4966c608fc71943e078148f07ebead7c720dbbb0 Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Thu, 24 Sep 2015 21:21:13 +0300 Subject: [PATCH] Provide helpful errors on JSON.parse exceptions The current code was using `jsonlint` as the default parser. I replaced it with `json-parse-helpfulerror` which uses JSON.parse by default and only if it throws it uses a different parser to provide helpful errors so in most cases the performance will be better. The alternative parser it uses is called `jju` and it provides really good clues to where the issue is. Other than that, I also added a test script to package.json, so you can run `npm test` to run the tests and updated the license field to use the valid format (without this, when ever you install cjson, npm will show a warning message that the package is missing the license field). --- .gitignore | 1 + index.js | 8 +++++--- package.json | 40 ++++++++++++++++++++++------------------ readme.md | 6 ++++-- test/test.js | 10 +++++----- 5 files changed, 37 insertions(+), 28 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/index.js b/index.js index dd8fb5e..d6ea855 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ var fs = require('fs'), Path = require('path'), - jsonlint = require('jsonlint'); + jph = require('json-parse-helpfulerror'); /** * Default options. @@ -16,8 +16,10 @@ exports.options = { freeze: false, // you can use any other extension for your config files, f.e. *.cjson ext: '.json', - // you can use any parser, f.e. you could switch to JSON.parse for speed - parse: jsonlint.parse + // you can use any parser you want. the default uses JSON.parse for maximum + // speed, if it throws it uses uses an alternative parser to give more + // helpful errors + parse: jph.parse } /** diff --git a/package.json b/package.json index f46570f..506f3da 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,24 @@ { - "name": "cjson", - "description": "cjson - Commented Javascript Object Notation. It is a json loader, which parses only valid json files, but with comments enabled. Useful for loading configs.", - "version": "0.3.1", - "repository": "git://github.com/kof/node-cjson.git", - "keywords": [ "json", "parser", "comments", "config", "loader"], - "author": "Oleg Slobodskoi ", - "engines": { - "node": ">= 0.3.0" - }, - "dependencies": { - "jsonlint": "1.6.0" - }, - "licenses": [ - { - "type": "MIT", - "url" : "http://www.opensource.org/licenses/mit-license.php" - } - ] + "name": "cjson", + "description": "cjson - Commented Javascript Object Notation. It is a json loader, which parses only valid json files, but with comments enabled. Useful for loading configs.", + "version": "0.3.1", + "repository": "git://github.com/kof/node-cjson.git", + "keywords": [ + "json", + "parser", + "comments", + "config", + "loader" + ], + "author": "Oleg Slobodskoi ", + "engines": { + "node": ">= 0.3.0" + }, + "dependencies": { + "json-parse-helpfulerror": "^1.0.3" + }, + "scripts": { + "test": "node ./test/test.js" + }, + "license": "MIT" } diff --git a/readme.md b/readme.md index 5b1a8b8..71dc47d 100644 --- a/readme.md +++ b/readme.md @@ -48,8 +48,10 @@ Load config file from given path, array of paths or directory. Second parameter freeze: false, // you can use any other extension for your config files, f.e. .cjson ext: '.json', - // you can use any parser, f.e. you could switch to JSON.parse for speed - parse: jsonlint.parse + // you can use any parser you want. the default uses JSON.parse for maximum + // speed, if it throws it uses uses an alternative parser to give more + // helpful errors + parse: jph.parse } diff --git a/test/test.js b/test/test.js index 8ddde59..6f1fa61 100644 --- a/test/test.js +++ b/test/test.js @@ -65,12 +65,12 @@ a.deepEqual(cjson.parse(str), data.conf2, '.parse method with comments'); try { cjson.load(fixtures + '/errors/invalid.cjson'); } catch (e) { - // Matching the line "Expecting ...." - var message = e.message.match(/^[^\^]*[^]\s(.*)\sFile:.*$/)[1]; - // Message was errorneously appended with a quote. + // Taking the first line from the error message + var message = e.message.split('\n')[0]; + // The error we expect is that the value ended with \n instead of quotes a.equal( - message, - "Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', got 'undefined'", + message.trim().toLowerCase(), + "unexpected token '\\n' at 2:17", 'Assert that the error message is properly formatted.' ); }