停止 Bluebird 承诺中的错误传播
Stop error propagation in Bluebird promises
如何阻止抛出的错误在整个链中传播?它显示在我的 catch()
块中,但它不会停止并因未捕获的异常而使服务器崩溃。
我 运行 这是节点 cron 作业 (node-cron) 的一部分:
var cronJob = require('cron').CronJob;
var cron = require('../lib/cron')
var c = new cronJob('* * * * * *', function() {
console.log('Cron starting');
mycode.run();
}, function() {
console.log('Cron executed');
}, true);
c.start();
在我的cron.js
module.exports = {
run: function() {
return job.getAndStore().catch(function(e) {
// This prints but it keeps on going so to speak - it doesn't 'catch', just notifies me
console.log('ERROR', e);
});
}
};
控制台转储:
Cron starting
ERROR [TypeError: undefined is not a function]
Cron starting
Uncaught Exception
[TypeError: undefined is not a function]
TypeError: undefined is not a function
我必须这样做,我知道不太正确:
try {
run();
} catch(e) {
console.log('Now it stops')
}
run()
是一些没有任何承诺支持的 cron 库的一部分,所以我将它包装在调用它的函数中。
Edit 因为我认为我的问题与后续调用有关,所以我认为这与我处理 2+ 次调用的 Mongo 连接的方式有关:
// Create a Mongo connection
Job.prototype.getDb = function(id) {
var self = this;
return new P(function(resolve, reject) {
if (!self.db) {
return Mongo.connectAsync(self.options.connection)
.then(function(c) {
self.db = c;
debug('Got new connection');
resolve(c);
});
}
debug('Got existing connection');
resolve(self.db);
});
};
// Fetch stuff
Job.prototype.getAndStore = function(c) {
return this.getDb().then(function() {
throw new Error('Boom');
});
};
您的 catch
回调仅在第一次执行。您在 cron 作业的第二个 运行 中遇到了未捕获的异常,看起来您的 job.getAndStore()
并没有 return 一个被拒绝的承诺,而是 throw
是同步的。不应该,它 should always return a promise.
您可以使用 Bluebirds Promise.try
to automatically catch such exceptions and transform them into a promise rejection. Or you wrap your getAndStore
function in Promise.method
:
var safeGetAndStore = Promise.method(job.getAndStore.bind(job));
module.exports = {
run: function() {
return safeGetAndStore().catch(function(e) {
console.log('ERROR', e);
});
}
};
在您的特定情况下,问题是您的 job
确实缓存了 db
连接并 return 在它已经可用时对其进行了编辑 - 但您需要 return 使用 .then
方法的承诺。您应该简单地缓存承诺本身:
Job.prototype.getDb = function(id) {
if (!this.db) {
this.db = Mongo.connectAsync(self.options.connection);
return this.db;
};
使用 done
,至少如果 bluebird 正确实施它,它会按您预期的那样工作。
catch(..)
只是 then(null, ..)
的别名,它是创建 另一个 承诺以供进一步处理的承诺转换器。
因此以下内容应该适合您:
module.exports = {
run: function() {
return job.getAndStore().done(null, function(e) {
// This prints but it keeps on going so to speak - it doesn't 'catch', just notifies me
console.log('ERROR', e);
});
}
};
如何阻止抛出的错误在整个链中传播?它显示在我的 catch()
块中,但它不会停止并因未捕获的异常而使服务器崩溃。
我 运行 这是节点 cron 作业 (node-cron) 的一部分:
var cronJob = require('cron').CronJob;
var cron = require('../lib/cron')
var c = new cronJob('* * * * * *', function() {
console.log('Cron starting');
mycode.run();
}, function() {
console.log('Cron executed');
}, true);
c.start();
在我的cron.js
module.exports = {
run: function() {
return job.getAndStore().catch(function(e) {
// This prints but it keeps on going so to speak - it doesn't 'catch', just notifies me
console.log('ERROR', e);
});
}
};
控制台转储:
Cron starting
ERROR [TypeError: undefined is not a function]
Cron starting
Uncaught Exception
[TypeError: undefined is not a function]
TypeError: undefined is not a function
我必须这样做,我知道不太正确:
try {
run();
} catch(e) {
console.log('Now it stops')
}
run()
是一些没有任何承诺支持的 cron 库的一部分,所以我将它包装在调用它的函数中。
Edit 因为我认为我的问题与后续调用有关,所以我认为这与我处理 2+ 次调用的 Mongo 连接的方式有关:
// Create a Mongo connection
Job.prototype.getDb = function(id) {
var self = this;
return new P(function(resolve, reject) {
if (!self.db) {
return Mongo.connectAsync(self.options.connection)
.then(function(c) {
self.db = c;
debug('Got new connection');
resolve(c);
});
}
debug('Got existing connection');
resolve(self.db);
});
};
// Fetch stuff
Job.prototype.getAndStore = function(c) {
return this.getDb().then(function() {
throw new Error('Boom');
});
};
您的 catch
回调仅在第一次执行。您在 cron 作业的第二个 运行 中遇到了未捕获的异常,看起来您的 job.getAndStore()
并没有 return 一个被拒绝的承诺,而是 throw
是同步的。不应该,它 should always return a promise.
您可以使用 Bluebirds Promise.try
to automatically catch such exceptions and transform them into a promise rejection. Or you wrap your getAndStore
function in Promise.method
:
var safeGetAndStore = Promise.method(job.getAndStore.bind(job));
module.exports = {
run: function() {
return safeGetAndStore().catch(function(e) {
console.log('ERROR', e);
});
}
};
在您的特定情况下,问题是您的 job
确实缓存了 db
连接并 return 在它已经可用时对其进行了编辑 - 但您需要 return 使用 .then
方法的承诺。您应该简单地缓存承诺本身:
Job.prototype.getDb = function(id) {
if (!this.db) {
this.db = Mongo.connectAsync(self.options.connection);
return this.db;
};
使用 done
,至少如果 bluebird 正确实施它,它会按您预期的那样工作。
catch(..)
只是 then(null, ..)
的别名,它是创建 另一个 承诺以供进一步处理的承诺转换器。
因此以下内容应该适合您:
module.exports = {
run: function() {
return job.getAndStore().done(null, function(e) {
// This prints but it keeps on going so to speak - it doesn't 'catch', just notifies me
console.log('ERROR', e);
});
}
};