Added loggign and more graceful error handling

no issue

- This is a quick implementation change to prevent from queue stalling and never becoming idle in case there's an error thrown from within the job function/module
- More robust error handling should be designed soon!
This commit is contained in:
Naz 2020-11-10 17:11:24 +13:00
parent 7dac72d6bf
commit 85b51524c9
2 changed files with 46 additions and 8 deletions

View File

@ -1,6 +1,7 @@
const fastq = require('fastq');
const later = require('@breejs/later');
const pWaitFor = require('p-wait-for');
const errors = require('@tryghost/errors');
const isCronExpression = require('./is-cron-expression');
const worker = async (task, callback) => {
@ -14,7 +15,8 @@ const worker = async (task, callback) => {
const handler = (error, result) => {
if (error) {
throw error;
// TODO: this handler should not be throwing as this blocks the queue
// throw error;
}
// Can potentially standardise the result here
return result;
@ -37,10 +39,24 @@ class JobManager {
this.logging.info('Adding one off job to the queue');
this.queue.push(async () => {
if (typeof job === 'function') {
await job(data);
} else {
await require(job)(data);
try {
if (typeof job === 'function') {
await job(data);
} else {
await require(job)(data);
}
} catch (err) {
// NOTE: each job should be written in a safe way and handle all errors internally
// if the error is caught here jobs implementaton should be changed
this.logging.error(new errors.IgnitionError({
level: 'critical',
errorType: 'UnhandledJobError',
message: 'Processed job threw an unhandled error',
context: (typeof job === 'function') ? 'function' : job,
err
}));
throw err;
}
}, handler);
}

View File

@ -5,11 +5,17 @@ const sinon = require('sinon');
const delay = require('delay');
const JobManager = require('../index');
const logging = {
info: sinon.stub()
};
describe('Job Manager', function () {
let logging;
beforeEach(() => {
logging = {
info: sinon.stub(),
error: sinon.stub()
};
});
it('public interface', function () {
const jobManager = new JobManager(logging);
@ -32,6 +38,22 @@ describe('Job Manager', function () {
should(spy.called).be.true();
should(spy.args[0][0]).equal('test data');
});
it('handles failed job gracefully', async function () {
const spy = sinon.stub().throws();
const jobManager = new JobManager(logging);
jobManager.addJob(spy, 'test data');
should(jobManager.queue.idle()).be.false();
// give time to execute the job
await delay(1);
should(jobManager.queue.idle()).be.true();
should(spy.called).be.true();
should(spy.args[0][0]).equal('test data');
should(logging.error.called).be.true();
});
});
describe('Schedule Job', function () {