diff --git a/index.js b/index.js index 6d68a19..2b8275f 100755 --- a/index.js +++ b/index.js @@ -26,10 +26,20 @@ exports.parse = function (path, map) { if(data) stream.write(data) if (header) - stream.emit('header', header) + stream.emit('header', header) if (footer) stream.emit('footer', footer) - stream.queue(null) + + if (parser.tState != Parser.C.START || parser.stack.length > 0) { + stream.emit('error', new Error('Incomplete JSON')) + if(!stream.writable && stream.autoDestroy) { + process.nextTick(function () { + stream.destroy() + }); + } + } else { + stream.queue(null) + } }) if('string' === typeof path) diff --git a/test/destroy_missing.js b/test/destroy_missing.js index 315fdc8..0740a4a 100644 --- a/test/destroy_missing.js +++ b/test/destroy_missing.js @@ -4,24 +4,27 @@ var join = require('path').join; var file = join(__dirname, 'fixtures','all_npm.json'); var JSONStream = require('../'); - -var server = net.createServer(function(client) { +var server = net.createServer(function(connection) { var parser = JSONStream.parse([]); - parser.on('end', function() { + parser.on('close', function() { console.log('close') console.error('PASSED'); server.close(); }); - client.pipe(parser); - var n = 4 - client.on('data', function () { - if(--n) return - client.end(); + parser.on('error', function (err) { + console.log('Parser error as expected: ' + err.message) + }) + connection.pipe(parser) + connection.on('data', function () { + connection.end(); }) }); -server.listen(9999); +server.listen(() => { + var port = server.address().port -var client = net.connect({ port : 9999 }, function() { - fs.createReadStream(file).pipe(client).on('data', console.log) //.resume(); -}); + console.log('Listening on port ' + port) + var client = net.connect({ port : port }, function() { + fs.createReadStream(file).pipe(client).on('data', console.log) //.resume(); + }); +}); \ No newline at end of file diff --git a/test/issues.js b/test/issues.js index ea4c743..3823ffc 100644 --- a/test/issues.js +++ b/test/issues.js @@ -1,34 +1,92 @@ -var JSONStream = require('../'); +var JSONStream = require('../') var test = require('tape') test('#66', function (t) { - var error = 0; + var error = 0 + var stream = JSONStream + .parse() + .on('error', function (err) { + t.ok(err, "error emitted: " + err.message + "\n" + err.stack) + error++ + }) + .on('close', function() { + t.ok(error === 2, "expect error to be called twice ('Invalid JSON', 'Incomplete JSON'): " + error) + t.end() + }) + stream.write('["foo":bar[') + stream.end() +}) + +test('#112 should allow aborting after first error', function (t) { + var error = 0 + var stream = JSONStream + .parse() + .on('error', function (err) { + t.ok(err, "error emitted: " + err.message + "\n" + err.stack) + error++ + stream.destroy() + }) + .on('close', function() { + t.ok(error === 1, "expect error to be called once: " + error) + t.end() + }) + stream.write('["foo":bar[') + stream.end() +}) + +test('#112 "Incomplete JSON" error is emitted', function (t) { var stream = JSONStream .parse() .on('error', function (err) { - t.ok(err); - error++; + t.ok("error emitted: " + err.message) + t.end() }) - .on('end', function () { - t.ok(error === 1); - t.end(); - }); - stream.write('["foo":bar['); - stream.end(); + stream.write('{"rows":[{"id":"id-1","name":"Name A"},{"id":"id-2","name":"') + stream.end() +}) -}); +test('#112 "Incomplete JSON" error is emitted with different JSON', function (t) { + var stream = JSONStream + .parse() + .on('error', function (err) { + t.ok("error emitted: " + err.message) + t.end() + }) + + stream.write('{"rows":[{"id":"id-1","name":"Name A"}') // I changed the incomplete JSON + stream.end() +}) + +test('#112 end is not emmitted after error', function (t) { + var ended = 0 + var stream = JSONStream + .parse() + .on('error', function (err) { + t.ok(err, "error emitted: " + err.message) + }) + .on('end', function () { + ended = 1 + }) + .on('close', function() { + t.ok(ended === 0 , "`end` emitted despite error") + t.end() + }) + + stream.write('{"rows":[{"id":"id-1","name":"Name A"},{"id":"id-2","name":"') + stream.end() +}) test('#81 - failure to parse nested objects', function (t) { var stream = JSONStream .parse('.bar.foo') .on('error', function (err) { - t.error(err); + t.error(err) }) .on('end', function () { - t.end(); - }); + t.end() + }) - stream.write('{"bar":{"foo":"baz"}}'); - stream.end(); -}); + stream.write('{"bar":{"foo":"baz"}}') + stream.end() +}) diff --git a/test/multiple_objects.js b/test/multiple_objects.js index 22f6324..e029b4c 100644 --- a/test/multiple_objects.js +++ b/test/multiple_objects.js @@ -28,9 +28,13 @@ var server = net.createServer(function(client) { }); client.pipe(parser); }); -server.listen(9999); -var client = net.connect({ port : 9999 }, function() { - var msgs = str + ' ' + str + '\n\n' + str - client.end(msgs); +server.listen(() => { + var port = server.address().port + + console.log('Listening on port ' + port) + var client = net.connect({ port : port }, function() { + var msgs = str + ' ' + str + '\n\n' + str + client.end(msgs); + }); }); diff --git a/test/multiple_objects_error.js b/test/multiple_objects_error.js index 83d113b..54b320e 100644 --- a/test/multiple_objects_error.js +++ b/test/multiple_objects_error.js @@ -21,9 +21,13 @@ var server = net.createServer(function(client) { }); client.pipe(parser); }); -server.listen(9999); -var client = net.connect({ port : 9999 }, function() { - var msgs = str + '}'; - client.end(msgs); +server.listen(() => { + var port = server.address().port + + console.log('Listening on port ' + port) + var client = net.connect({ port : port }, function() { + var msgs = str + '}'; + client.end(msgs); + }); });