diff --git a/index.js b/index.js index 45cbeac..56dab81 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ var fs = require('fs'); var path = require('path'); -var relativePath = require('cached-path-relative') +var relativePath = require('cached-path-relative'); var browserResolve = require('browser-resolve'); var nodeResolve = require('resolve'); @@ -206,8 +206,6 @@ Deps.prototype.readFile = function (file, id, pkg) { var rs = fs.createReadStream(file, { encoding: 'utf8' }); - rs.on('error', function (err) { self.emit('error', err) }); - this.emit('file', file, id); return rs; }; @@ -235,7 +233,9 @@ Deps.prototype.getTransforms = function (file, pkg, opts) { for (var i = 0; i < transforms.length; i++) (function (i) { makeTransform(transforms[i], function (err, trs) { - if (err) return self.emit('error', err) + if (err) { + return dup.emit('error', err); + } streams[i] = trs; if (-- pending === 0) done(); }); @@ -247,7 +247,7 @@ Deps.prototype.getTransforms = function (file, pkg, opts) { middle.on('error', function (err) { err.message += ' while parsing file: ' + file; if (!err.filename) err.filename = file; - self.emit('error', err); + dup.emit('error', err); }); input.pipe(middle).pipe(output); } @@ -280,7 +280,7 @@ Deps.prototype.getTransforms = function (file, pkg, opts) { if (err) { params.basedir = pkg.__dirname; return nodeResolve(id, params, function (e, r) { - nr(e, r, true) + nr(e, r, true); }); } @@ -346,6 +346,9 @@ Deps.prototype.walk = function (id, parent, cb) { file = rec.file; var ts = self.getTransforms(file, pkg); + ts.on('error', function (err) { + self.emit('error', err); + }); ts.pipe(concat(function (body) { rec.source = body.toString('utf8'); fromSource(file, rec.source, pkg); @@ -368,6 +371,9 @@ Deps.prototype.walk = function (id, parent, cb) { if (rec.source) { var ts = self.getTransforms(file, pkg); + ts.on('error', function (err) { + self.emit('error', err); + }); ts.pipe(concat(function (body) { rec.source = body.toString('utf8'); fromSource(file, rec.source, pkg); @@ -379,6 +385,7 @@ Deps.prototype.walk = function (id, parent, cb) { if (c) return fromDeps(file, c.source, c.package, fakePath, Object.keys(c.deps)); self.persistentCache(file, id, pkg, persistentCacheFallback, function (err, c) { + self.emit('file', file, id); if (err) { self.emit('error', err); return; @@ -387,12 +394,13 @@ Deps.prototype.walk = function (id, parent, cb) { }); function persistentCacheFallback (dataAsString, cb) { - var stream = dataAsString ? toStream(dataAsString) : self.readFile(file, id, pkg); + var stream = dataAsString ? toStream(dataAsString) : self.readFile(file, id, pkg).on('error', cb); stream .pipe(self.getTransforms(fakePath || file, pkg, { builtin: builtin, inNodeModules: parent.inNodeModules })) + .on('error', cb) .pipe(concat(function (body) { var src = body.toString('utf8'); var deps = getDeps(file, src); @@ -521,7 +529,7 @@ Deps.prototype.lookupPackage = function (file, cb) { catch (err) { return onpkg(new Error([ err + ' while parsing json file ' + pkgfile - ].join(''))) + ].join(''))); } pkg.__dirname = dir; @@ -536,8 +544,8 @@ Deps.prototype.lookupPackage = function (file, cb) { delete self.pkgFileCachePending[pkgfile]; fns.forEach(function (f) { f(err, pkg) }); } - if (err) cb(err) - else if (pkg) cb(null, pkg) + if (err) cb(err); + else if (pkg) cb(null, pkg); else { self.pkgCache[pkgfile] = false; next(); diff --git a/test/cache_persistent.js b/test/cache_persistent.js index 8c18734..13c827e 100644 --- a/test/cache_persistent.js +++ b/test/cache_persistent.js @@ -13,13 +13,13 @@ test('uses persistent cache', function (t) { var p = parser({ persistentCache: function (file, id, pkg, fallback, cb) { if (file === files.bar) { - return fallback(null, cb) + return fallback(null, cb); } cb(null, { source: 'file at ' + file + '@' + id, package: pkg, deps: { './bar': files.bar } - }) + }); } }); p.end({ id: 'foo', file: files.foo, entry: false }); @@ -48,7 +48,7 @@ test('passes persistent cache error through', function (t) { t.plan(1); var p = parser({ persistentCache: function (file, id, pkg, fallback, cb) { - cb(new Error('foo')) + cb(new Error('foo')); } }); p.end({ id: 'foo', file: files.foo, entry: false }); @@ -59,7 +59,7 @@ test('allow passing of the raw source as string', function (t) { t.plan(1); var p = parser({ persistentCache: function (file, id, pkg, fallback, cb) { - fallback(fs.readFileSync(files.bar, 'utf8'), cb) + fallback(fs.readFileSync(files.bar, 'utf8'), cb); } }); p.end({ id: 'foo', file: files.foo, entry: false }); @@ -78,4 +78,45 @@ test('allow passing of the raw source as string', function (t) { }); }); +test('send file event with persistent cache', function (t) { + t.plan(2); + var p = parser({ + persistentCache: function (file, id, pkg, fallback, cb) { + cb(null, { + source: 'file at ' + file + '@' + id, + package: pkg, + deps: {} + }); + } + }); + p.end({ id: 'foo', file: files.foo, entry: false }); + p.on('file', function (file, id) { + t.same(file, path.resolve(files.foo)); + t.same(id, path.resolve(files.foo)); + }); +}); + +test('errors of transforms occur in the correct order with a persistent cache', function (t) { + t.plan(3); + var p = parser({ + transform: [ + path.join(__dirname, 'cache_persistent', 'error_transform') + ], + persistentCache: function (file, id, pkg, fallback, cb) { + fallback(fs.readFileSync(files.foo, 'utf8'), cb); + } + }); + p.end({ id: 'foo', file: files.foo, entry: false }); + var order = 0; + p.on('file', function (file, id) { + t.same(order, 0); + order += 1; + }); + p.on('error', function (err) { + t.same(order, 1); + t.same(err.message, 'rawr while parsing file: ' + path.resolve(files.foo)); + }); +}); + + function cmp (a, b) { return a.id < b.id ? -1 : 1 } diff --git a/test/cache_persistent/error_transform.js b/test/cache_persistent/error_transform.js new file mode 100644 index 0000000..0cfddab --- /dev/null +++ b/test/cache_persistent/error_transform.js @@ -0,0 +1,6 @@ +var through = require('through2'); +module.exports = function (file) { + return through(function (chunk, enc, callback) { + callback(new Error('rawr')); + }); +};