mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-23 22:11:09 +03:00
✨ Added errorHandler option to customize job error logic
closes https://github.com/TryGhost/Ghost-Utils/issues/118 - Custom error handling is needed to be able to override default bree error handling logic. - bree bump to 4.1.0 also fixed logging errors (object Object fix in tests) - The handler function receives two parameters. First contains an error that has been thrown by the job. Second, job and worker metadata
This commit is contained in:
parent
0aff1a305e
commit
c13d8a2fa6
@ -26,14 +26,20 @@ const handler = (error, result) => {
|
||||
};
|
||||
|
||||
class JobManager {
|
||||
constructor(logging) {
|
||||
/**
|
||||
* @param {Object} options
|
||||
* @param {Object} [options.logging] - custom logging handler, defaults to console
|
||||
* @param {Function} [options.errorHandler] - custom job error handler
|
||||
*/
|
||||
constructor({logging, errorHandler}) {
|
||||
this.queue = fastq(this, worker, 1);
|
||||
|
||||
this.bree = new Bree({
|
||||
root: false, // set this to `false` to prevent requiring a root directory of jobs
|
||||
hasSeconds: true, // precission is needed to avoid task ovelaps after immidiate execution
|
||||
outputWorkerMetadata: true,
|
||||
logger: logging
|
||||
logger: logging,
|
||||
errorHandler: errorHandler
|
||||
});
|
||||
|
||||
this.logging = logging;
|
||||
|
@ -28,7 +28,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@breejs/later": "4.0.2",
|
||||
"bree": "4.0.0",
|
||||
"bree": "4.1.0",
|
||||
"cron-validate": "1.4.1",
|
||||
"fastq": "1.9.0",
|
||||
"p-wait-for": "3.1.0"
|
||||
|
@ -20,7 +20,7 @@ describe('Job Manager', function () {
|
||||
});
|
||||
|
||||
it('public interface', function () {
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
|
||||
should.exist(jobManager.addJob);
|
||||
should.exist(jobManager.scheduleJob);
|
||||
@ -29,7 +29,7 @@ describe('Job Manager', function () {
|
||||
describe('Add a Job', function () {
|
||||
it('adds a job to a queue', async function () {
|
||||
const spy = sinon.spy();
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
|
||||
jobManager.addJob(spy, 'test data');
|
||||
should(jobManager.queue.idle()).be.false();
|
||||
@ -44,7 +44,7 @@ describe('Job Manager', function () {
|
||||
|
||||
it('handles failed job gracefully', async function () {
|
||||
const spy = sinon.stub().throws();
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
|
||||
jobManager.addJob(spy, 'test data');
|
||||
should(jobManager.queue.idle()).be.false();
|
||||
@ -61,7 +61,7 @@ describe('Job Manager', function () {
|
||||
|
||||
describe('Schedule a Job', function () {
|
||||
it('fails to schedule for invalid scheduling expression', function () {
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
|
||||
try {
|
||||
jobManager.scheduleJob('invalid expression', 'jobName', {});
|
||||
@ -71,7 +71,7 @@ describe('Job Manager', function () {
|
||||
});
|
||||
|
||||
it('fails to schedule for no job name', function () {
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
|
||||
try {
|
||||
jobManager.scheduleJob('invalid expression', () => {}, {});
|
||||
@ -81,7 +81,7 @@ describe('Job Manager', function () {
|
||||
});
|
||||
|
||||
it('schedules a job using date format', async function () {
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
const timeInTenSeconds = new Date(Date.now() + 10);
|
||||
const jobPath = path.resolve(__dirname, './jobs/simple.js');
|
||||
|
||||
@ -115,7 +115,7 @@ describe('Job Manager', function () {
|
||||
});
|
||||
|
||||
it('schedules a job to run immediately', async function () {
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
const clock = FakeTimers.install({now: Date.now()});
|
||||
|
||||
const jobPath = path.resolve(__dirname, './jobs/simple.js');
|
||||
@ -144,7 +144,7 @@ describe('Job Manager', function () {
|
||||
});
|
||||
|
||||
it('fails to schedule a job with the same name to run immediately one after another', async function () {
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
const clock = FakeTimers.install({now: Date.now()});
|
||||
|
||||
const jobPath = path.resolve(__dirname, './jobs/simple.js');
|
||||
@ -169,19 +169,34 @@ describe('Job Manager', function () {
|
||||
|
||||
should(jobManager.bree.workers['job-now']).type('undefined');
|
||||
|
||||
// note: job name resolves to [Object object], test can be made more precise
|
||||
// once that is fixed in Bree.
|
||||
(() => {
|
||||
jobManager.scheduleJob(undefined, jobPath, undefined, 'job-now');
|
||||
}).should.throw('Job #1 has a duplicate job name of [object Object]');
|
||||
}).should.throw('Job #1 has a duplicate job name of job-now');
|
||||
|
||||
clock.uninstall();
|
||||
});
|
||||
|
||||
it('uses custom error handler when job fails', async function (){
|
||||
let job = function namedJob() {
|
||||
throw new Error('job error');
|
||||
};
|
||||
const spyHandler = sinon.spy();
|
||||
const jobManager = new JobManager({logging, errorHandler: spyHandler});
|
||||
|
||||
jobManager.scheduleJob(undefined, job, undefined, 'will-fail');
|
||||
|
||||
// give time to execute the job
|
||||
await delay(100);
|
||||
|
||||
should(spyHandler.called).be.true();
|
||||
should(spyHandler.args[0][0].message).equal('job error');
|
||||
should(spyHandler.args[1][1].name).equal('will-fail');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Remove a Job', function () {
|
||||
it('removes a scheduled job from the queue', async function () {
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
|
||||
const timeInTenSeconds = new Date(Date.now() + 10);
|
||||
const jobPath = path.resolve(__dirname, './jobs/simple.js');
|
||||
@ -197,7 +212,7 @@ describe('Job Manager', function () {
|
||||
|
||||
describe('Shutdown', function () {
|
||||
it('gracefully shuts down a synchronous jobs', async function () {
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
|
||||
jobManager.addJob(require('./jobs/timed-job'), 200);
|
||||
|
||||
@ -209,7 +224,7 @@ describe('Job Manager', function () {
|
||||
});
|
||||
|
||||
it('gracefully shuts down an interval job', async function () {
|
||||
const jobManager = new JobManager(logging);
|
||||
const jobManager = new JobManager({logging});
|
||||
|
||||
jobManager.scheduleJob('every 5 seconds', path.resolve(__dirname, './jobs/graceful.js'));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user