Skip to content

Commit 39b598e

Browse files
UzlopakAras Abbasi
and
Aras Abbasi
authored
fix: rename err to error, fix typing of DefinitionProcessor, use debug ins… (#9)
* rename err to error, fix typing of DefinitionProcessor, use debug instead of console, throw error when createIndex fails * rename err to error * more typings * revert DefinitionProcessor Co-authored-by: Aras Abbasi <a.abbasi@cognigy.com>
1 parent 5fd44b8 commit 39b598e

File tree

6 files changed

+93
-44
lines changed

6 files changed

+93
-44
lines changed

src/Job.ts

+19-22
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,9 @@ export class Job<DATA = unknown | void> {
237237
} else {
238238
this.attrs.nextRunAt = null;
239239
}
240-
} catch (err) {
240+
} catch (error) {
241241
this.attrs.nextRunAt = null;
242-
this.fail(err);
242+
this.fail(error);
243243
}
244244

245245
return this;
@@ -271,22 +271,19 @@ export class Job<DATA = unknown | void> {
271271
log('[%s:%s] process function being called', this.attrs.name, this.attrs._id);
272272
await new Promise((resolve, reject) => {
273273
try {
274-
const result = (definition.fn as DefinitionProcessor<DATA, (err?) => void>)(
275-
this,
276-
err => {
277-
if (err) {
278-
reject(err);
279-
return;
280-
}
281-
resolve();
274+
const result = definition.fn(this, error => {
275+
if (error) {
276+
reject(error);
277+
return;
282278
}
283-
);
279+
resolve();
280+
});
281+
284282
if (this.isPromise(result)) {
285-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
286-
(result as any).catch(err => reject(err));
283+
result.catch((error: Error) => reject(error));
287284
}
288-
} catch (err) {
289-
reject(err);
285+
} catch (error) {
286+
reject(error);
290287
}
291288
});
292289
} else {
@@ -299,14 +296,14 @@ export class Job<DATA = unknown | void> {
299296
this.agenda.emit('success', this);
300297
this.agenda.emit(`success:${this.attrs.name}`, this);
301298
log('[%s:%s] has succeeded', this.attrs.name, this.attrs._id);
302-
} catch (err) {
299+
} catch (error) {
303300
log('[%s:%s] unknown error occurred', this.attrs.name, this.attrs._id);
304301

305-
this.fail(err);
302+
this.fail(error);
306303

307-
this.agenda.emit('fail', err, this);
308-
this.agenda.emit(`fail:${this.attrs.name}`, err, this);
309-
log('[%s:%s] has failed [%s]', this.attrs.name, this.attrs._id, err.message);
304+
this.agenda.emit('fail', error, this);
305+
this.agenda.emit(`fail:${this.attrs.name}`, error, this);
306+
log('[%s:%s] has failed [%s]', this.attrs.name, this.attrs._id, error.message);
310307
} finally {
311308
this.attrs.lockedAt = undefined;
312309
await this.save();
@@ -323,7 +320,7 @@ export class Job<DATA = unknown | void> {
323320
}
324321
}
325322

326-
private isPromise(value): value is Promise<void> {
327-
return !!(value && typeof value.then === 'function');
323+
private isPromise(value: unknown): value is Promise<void> {
324+
return !!(value && typeof (value as Promise<void>).then === 'function');
328325
}
329326
}

src/JobDbRepository.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ export class JobDbRepository {
4343
throw new Error('invalid db config, or db config not found');
4444
}
4545

46-
private hasMongoConnection(connectOptions): connectOptions is IMongoOptions {
47-
return !!connectOptions.mongo;
46+
private hasMongoConnection(connectOptions: unknown): connectOptions is IMongoOptions {
47+
return !!(connectOptions as IMongoOptions)?.mongo;
4848
}
4949

50-
private hasDatabaseConfig(connectOptions): connectOptions is IDatabaseOptions {
51-
return !!connectOptions.db?.address;
50+
private hasDatabaseConfig(connectOptions: unknown): connectOptions is IDatabaseOptions {
51+
return !!(connectOptions as IDatabaseOptions)?.db?.address;
5252
}
5353

5454
async getJobs(
@@ -193,8 +193,9 @@ export class JobDbRepository {
193193
{ name: 'findAndLockNextJobIndex' }
194194
);
195195
log('index succesfully created', result);
196-
} catch (err) {
197-
console.error('db index creation failed', err);
196+
} catch (error) {
197+
log('db index creation failed', error);
198+
throw error;
198199
}
199200
}
200201

src/JobProcessor.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ export class JobProcessor {
310310
* @param {String} name fill a queue with specific job name
311311
* @returns {undefined}
312312
*/
313-
private async jobQueueFilling(name) {
313+
private async jobQueueFilling(name: string): Promise<void> {
314314
// Don't lock because of a limit we have set (lockLimit, etc)
315315
if (!this.shouldLock(name)) {
316316
log.extend('jobQueueFilling')('lock limit reached in queue filling for [%s]', name);
@@ -529,16 +529,16 @@ export class JobProcessor {
529529
`callback already called - job ${job.attrs.name} already marked complete`
530530
);
531531
}
532-
} catch (err) {
532+
} catch (error) {
533533
// eslint-disable-next-line no-param-reassign
534-
job.canceled = err;
534+
job.canceled = error;
535535
log.extend('runOrRetry')(
536536
'[%s:%s] processing job failed',
537537
job.attrs.name,
538538
job.attrs._id,
539-
err
539+
error
540540
);
541-
this.agenda.emit('error', err);
541+
this.agenda.emit('error', error);
542542
} finally {
543543
// Remove the job from the running queue
544544
let runningJobIndex = this.runningJobs.indexOf(job);

src/index.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ export class Agenda extends EventEmitter {
4545
// internally used
4646
on(event: 'processJob', listener: (job: Job) => void): this;
4747

48-
on(event: 'fail', listener: (err: Error, job: Job) => void): this;
48+
on(event: 'fail', listener: (error: Error, job: Job) => void): this;
4949
on(event: 'success', listener: (job: Job) => void): this;
5050
on(event: 'start', listener: (job: Job) => void): this;
5151
on(event: 'complete', listener: (job: Job) => void): this;
5252
on(event: string, listener: (job: Job) => void): this;
53-
on(event: string, listener: (err: Error, job: Job) => void): this;
53+
on(event: string, listener: (error: Error, job: Job) => void): this;
5454
on(event: 'ready', listener: () => void): this;
55-
on(event: 'error', listener: (err: Error) => void): this;
55+
on(event: 'error', listener: (error: Error) => void): this;
5656
on(event: string, listener: (...args) => void): this {
5757
return super.on(event, listener);
5858
}
@@ -84,7 +84,7 @@ export class Agenda extends EventEmitter {
8484
// eslint-disable-next-line @typescript-eslint/ban-types
8585
} & (IDatabaseOptions | IMongoOptions | {}) &
8686
IDbConfig = {},
87-
cb?: (err?: Error) => void
87+
cb?: (error?: Error) => void
8888
) {
8989
super();
9090

@@ -133,8 +133,10 @@ export class Agenda extends EventEmitter {
133133
return this;
134134
}
135135

136-
private hasDatabaseConfig(config): config is (IDatabaseOptions | IMongoOptions) & IDbConfig {
137-
return !!(config.db?.address || config.mongo);
136+
private hasDatabaseConfig(
137+
config: unknown
138+
): config is (IDatabaseOptions | IMongoOptions) & IDbConfig {
139+
return !!((config as IDatabaseOptions)?.db?.address || (config as IMongoOptions)?.mongo);
138140
}
139141

140142
async cancel(query: FilterQuery<IJobParameters>): Promise<number> {
@@ -215,7 +217,7 @@ export class Agenda extends EventEmitter {
215217
// eslint-disable-next-line @typescript-eslint/no-explicit-any
216218
define<DATA = any>(
217219
name: string,
218-
processor: (agendaJob: Job<DATA>, done: (err?: Error) => void) => void,
220+
processor: (agendaJob: Job<DATA>, done: (error?: Error) => void) => void,
219221
options?: Partial<Pick<IJobDefinition, 'lockLimit' | 'lockLifetime' | 'concurrency'>> & {
220222
priority?: JobPriority;
221223
}
@@ -230,13 +232,13 @@ export class Agenda extends EventEmitter {
230232
): void;
231233
define(
232234
name: string,
233-
processor: ((job) => Promise<void>) | ((job, done) => void),
235+
processor: ((job: Job) => Promise<void>) | ((job: Job, done) => void),
234236
options?: Partial<Pick<IJobDefinition, 'lockLimit' | 'lockLifetime' | 'concurrency'>> & {
235237
priority?: JobPriority;
236238
}
237239
): void {
238240
if (this.definitions[name]) {
239-
console.warn('overwriting already defined agenda job', name);
241+
log('overwriting already defined agenda job', name);
240242
}
241243
this.definitions[name] = {
242244
fn: processor,
@@ -355,7 +357,7 @@ export class Agenda extends EventEmitter {
355357
names: string | string[],
356358
data?: unknown
357359
): Promise<Job | Job[]> {
358-
const createJob = async name => {
360+
const createJob = async (name: string) => {
359361
const job = this.create(name, data);
360362

361363
await job.schedule(when).save();

src/types/JobDefinition.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export interface IJobDefinition<DATA = unknown> {
1010
/** how many jobs of this kind can run in parallel/simultanously per Agenda instance */
1111
concurrency?: number;
1212

13-
fn: DefinitionProcessor<DATA, void | ((err?: Error) => void)>;
13+
fn: DefinitionProcessor<DATA, void | ((error?: Error) => void)>;
1414
}
1515

1616
export type DefinitionProcessor<DATA, CB> = (

test/agenda.test.ts

+49
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,55 @@ describe('Agenda', () => {
610610
});
611611
});
612612

613+
describe('ensureIndex findAndLockNextJobIndex', () => {
614+
it('ensureIndex-Option false does not create index findAndLockNextJobIndex', async () => {
615+
const agenda = new Agenda({
616+
mongo: mongoDb,
617+
ensureIndex: false
618+
});
619+
620+
agenda.define('someJob', jobProcessor);
621+
await agenda.create('someJob', 1).save();
622+
623+
const listIndex = await mongoDb.command({ listIndexes: 'agendaJobs' });
624+
expect(listIndex.cursor.firstBatch).to.have.lengthOf(1);
625+
expect(listIndex.cursor.firstBatch[0].name).to.be.equal('_id_');
626+
});
627+
628+
it('ensureIndex-Option true does create index findAndLockNextJobIndex', async () => {
629+
const agenda = new Agenda({
630+
mongo: mongoDb,
631+
ensureIndex: true
632+
});
633+
634+
agenda.define('someJob', jobProcessor);
635+
await agenda.create('someJob', 1).save();
636+
637+
const listIndex = await mongoDb.command({ listIndexes: 'agendaJobs' });
638+
expect(listIndex.cursor.firstBatch).to.have.lengthOf(2);
639+
expect(listIndex.cursor.firstBatch[0].name).to.be.equal('_id_');
640+
expect(listIndex.cursor.firstBatch[1].name).to.be.equal('findAndLockNextJobIndex');
641+
});
642+
643+
it('creating two agenda-instances with ensureIndex-Option true does not throw an error', async () => {
644+
const agenda = new Agenda({
645+
mongo: mongoDb,
646+
ensureIndex: true
647+
});
648+
649+
agenda.define('someJob', jobProcessor);
650+
await agenda.create('someJob', 1).save();
651+
652+
const secondAgenda = new Agenda({
653+
mongo: mongoDb,
654+
ensureIndex: true
655+
});
656+
657+
secondAgenda.define('someJob', jobProcessor);
658+
await secondAgenda.create('someJob', 1).save();
659+
});
660+
});
661+
613662
describe('process jobs', () => {
614663
// eslint-disable-line prefer-arrow-callback
615664
it('should not cause unhandledRejection', async () => {

0 commit comments

Comments
 (0)