Skip to content

Commit

Permalink
feat: distinguish argument error
Browse files Browse the repository at this point in the history
  • Loading branch information
yujiosaka committed Oct 25, 2023
1 parent cf9eaa0 commit 279dca2
Show file tree
Hide file tree
Showing 9 changed files with 27 additions and 22 deletions.
6 changes: 3 additions & 3 deletions examples/job-stores/custom-job-store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bun
import { isEqual } from "date-fns";
import { v4 } from "uuid";
import Cronyx, { BaseJobLock, JobLockNotFoundError } from "../../src";
import Cronyx, { BaseJobLock, CronyxNotFoundError } from "../../src";
import type BaseJobStore from "../../src/job-store";

// Create a new cache by extending BaseJobStore interface
Expand Down Expand Up @@ -67,7 +67,7 @@ export default class MemoryJobStore implements BaseJobStore<string> {
async deactivateJobLock(jobName: string, jobId: string): Promise<BaseJobLock<string>> {
const lastJobLock = await this.fetchLastJobLock(jobName);
if (!lastJobLock || !lastJobLock.isActive || lastJobLock._id !== jobId) {
throw new JobLockNotFoundError(`Cannot find job lock for ${jobName}`);
throw new CronyxNotFoundError(`Cannot find job lock for ${jobName}`);
}

const detivatedJobLock = { ...lastJobLock, isActive: false, updatedAt: new Date() };
Expand All @@ -79,7 +79,7 @@ export default class MemoryJobStore implements BaseJobStore<string> {
async removeJobLock(jobName: string, jobId: string): Promise<void> {
const lastJobLock = await this.fetchLastJobLock(jobName);
if (!lastJobLock || lastJobLock._id !== jobId) {
throw new JobLockNotFoundError(`Cannot find job lock for ${jobName}`);
throw new CronyxNotFoundError(`Cannot find job lock for ${jobName}`);
}

this.#jobLocks[jobName].pop();
Expand Down
7 changes: 6 additions & 1 deletion src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@ export class CronyxError extends Error {
/**
* @public
*/
export class JobLockNotFoundError extends Error {}
export class CronyxArgumentError extends CronyxError {}

/**
* @public
*/
export class CronyxNotFoundError extends CronyxError {}
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export { default as TypeormJobStore } from "./job-store/typeorm";
export { default as MysqlJobStore } from "./job-store/typeorm/mysql";
export { default as PostgresJobStore } from "./job-store/typeorm/postgres";
export { default as Job } from "./job";
export { CronyxError, JobLockNotFoundError } from "./error";
export { CronyxError, CronyxArgumentError, CronyxNotFoundError } from "./error";

/**
* @public
Expand Down
4 changes: 2 additions & 2 deletions src/job-runner.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Duration } from "date-fns";
import { differenceInMilliseconds } from "date-fns";
import { CronyxError } from "./error";
import { CronyxArgumentError, CronyxError } from "./error";
import Job from "./job";
import type BaseJobLock from "./job-lock";
import MockJobLock from "./job-lock/mock";
Expand Down Expand Up @@ -62,7 +62,7 @@ export default class JobRunner<I> {

async requestJobStart(): Promise<Job<I> | null> {
if (this.#jobIntervalStartedAt) {
if (!this.#noLock) throw new CronyxError("Should enable `noLock` when `jobIntervalStartedAt` is passed");
if (!this.#noLock) throw new CronyxArgumentError("Should enable `noLock` when `jobIntervalStartedAt` is passed");

const jobIntervalEndedAt = addInterval(this.#jobIntervalStartedAt, this.#jobInterval, this.#timezone);
const jobInterval = differenceInMilliseconds(jobIntervalEndedAt, this.#jobIntervalStartedAt);
Expand Down
6 changes: 3 additions & 3 deletions src/job-store/mongodb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { MongoClientOptions } from "mongodb";
import { createConnection } from "mongoose";
import type { Connection, Model, Types } from "mongoose";
import type BaseJobStore from ".";
import { JobLockNotFoundError } from "../error";
import { CronyxNotFoundError } from "../error";
import type MongodbJobLock from "../job-lock/mongodb";
import { mongodbJobLockSchema } from "../job-lock/mongodb";

Expand Down Expand Up @@ -62,13 +62,13 @@ export default class MongodbJobStore implements BaseJobStore<Types.ObjectId> {
{ isActive: false, updatedAt: new Date() },
{ new: true },
);
if (!deactivatedJobLock) throw new JobLockNotFoundError(`Cannot find job lock for ${jobName}`);
if (!deactivatedJobLock) throw new CronyxNotFoundError(`Cannot find job lock for ${jobName}`);

return deactivatedJobLock;
}

async removeJobLock(jobName: string, jobId: Types.ObjectId): Promise<void> {
const result = await this.#model.deleteOne({ _id: jobId, jobName, isActive: true });
if (result.deletedCount === 0) throw new JobLockNotFoundError(`Cannot find job lock for ${jobName}`);
if (result.deletedCount === 0) throw new CronyxNotFoundError(`Cannot find job lock for ${jobName}`);
}
}
6 changes: 3 additions & 3 deletions src/job-store/redis.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isEqual } from "date-fns";
import { createClient, RedisClientOptions, WatchError } from "redis";
import type BaseJobStore from ".";
import { JobLockNotFoundError } from "../error";
import { CronyxNotFoundError } from "../error";
import RedisJobLock from "../job-lock/redis";

const ACTIVE_JOB_LOCK_PREFIX = "joblocks:active:";
Expand Down Expand Up @@ -101,7 +101,7 @@ export default class RedisJobStore implements BaseJobStore<string> {
async deactivateJobLock(jobName: string, jobId: string): Promise<RedisJobLock> {
const activeJobLock = await this.#getActiveJobLock(jobName);
if (!activeJobLock || activeJobLock._id !== jobId) {
throw new JobLockNotFoundError(`Cannot find job lock for ${jobName}`);
throw new CronyxNotFoundError(`Cannot find job lock for ${jobName}`);
}

const detivatedJobLock = { ...activeJobLock, isActive: false, updatedAt: new Date() };
Expand All @@ -117,7 +117,7 @@ export default class RedisJobStore implements BaseJobStore<string> {
async removeJobLock(jobName: string, jobId: string): Promise<void> {
const activeJobLock = await this.#getActiveJobLock(jobName);
if (!activeJobLock || activeJobLock._id !== jobId) {
throw new JobLockNotFoundError(`Cannot find job lock for ${jobName}`);
throw new CronyxNotFoundError(`Cannot find job lock for ${jobName}`);
}

await this.#client.del(`${ACTIVE_JOB_LOCK_PREFIX}${jobName}`);
Expand Down
6 changes: 3 additions & 3 deletions src/job-store/typeorm/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Repository } from "typeorm";
import { DataSource } from "typeorm";
import type BaseJobStore from "..";
import { JobLockNotFoundError } from "../../error";
import { CronyxNotFoundError } from "../../error";
import { TypeormJobLockEntity } from "../../job-lock/typeorm";
import type TypeormJobLock from "../../job-lock/typeorm";
import { hasErrorCode } from "../../util";
Expand Down Expand Up @@ -75,13 +75,13 @@ export default abstract class TypeormJobStore implements BaseJobStore<string> {

async deactivateJobLock(jobName: string, jobId: string): Promise<TypeormJobLock> {
const deactivatedJobLock = await this.#repository.findOne({ where: { _id: jobId, jobName, isActive: true } });
if (!deactivatedJobLock) throw new JobLockNotFoundError(`Cannot find job lock for ${jobName}`);
if (!deactivatedJobLock) throw new CronyxNotFoundError(`Cannot find job lock for ${jobName}`);

return await this.#repository.save({ ...deactivatedJobLock, isActive: false, updatedAt: new Date() });
}

async removeJobLock(jobName: string, jobId: string): Promise<void> {
const result = await this.#repository.delete({ _id: jobId, jobName, isActive: true });
if (result.affected === 0) throw new JobLockNotFoundError(`Cannot find job lock for ${jobName}`);
if (result.affected === 0) throw new CronyxNotFoundError(`Cannot find job lock for ${jobName}`);
}
}
6 changes: 3 additions & 3 deletions src/job-store/typeorm/mysql.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DataSource } from "typeorm";
import type { AuroraMysqlConnectionOptions } from "typeorm/driver/aurora-mysql/AuroraMysqlConnectionOptions.js";
import type { MysqlConnectionOptions } from "typeorm/driver/mysql/MysqlConnectionOptions.js";
import { CronyxError } from "../../error";
import { CronyxArgumentError } from "../../error";
import { TypeormJobLockEntity } from "../../job-lock/typeorm";
import TypeormJobStore from "./";

Expand All @@ -12,8 +12,8 @@ export default class MysqlJobStore extends TypeormJobStore {
protected uniqueConstraintErrorCode: string = "ER_DUP_ENTRY";

static async connect(options: MysqlConnectionOptions | AuroraMysqlConnectionOptions): Promise<TypeormJobStore> {
if (!options.synchronize === false) throw new CronyxError("Option synchronize should be enabled");
if (options.entities) throw new CronyxError("Option entities should not be passed");
if (!options.synchronize === false) throw new CronyxArgumentError("Option synchronize should be enabled");
if (options.entities) throw new CronyxArgumentError("Option entities should not be passed");

const dataSource = new DataSource({ ...options, entities: [TypeormJobLockEntity], synchronize: true });
await dataSource.initialize();
Expand Down
6 changes: 3 additions & 3 deletions src/job-store/typeorm/postgres.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DataSource } from "typeorm";
import type { AuroraPostgresConnectionOptions } from "typeorm/driver/aurora-postgres/AuroraPostgresConnectionOptions.js";
import type { PostgresConnectionOptions } from "typeorm/driver/postgres/PostgresConnectionOptions.js";
import { CronyxError } from "../../error";
import { CronyxArgumentError } from "../../error";
import { TypeormJobLockEntity } from "../../job-lock/typeorm";
import TypeormJobStore from "./";

Expand All @@ -12,8 +12,8 @@ export default class PostgresJobStore extends TypeormJobStore {
protected uniqueConstraintErrorCode: string = "23505";

static async connect(options: PostgresConnectionOptions | AuroraPostgresConnectionOptions): Promise<TypeormJobStore> {
if (!options.synchronize === false) throw new CronyxError("Option synchronize should be enabled");
if (options.entities) throw new CronyxError("Option entities should not be passed");
if (!options.synchronize === false) throw new CronyxArgumentError("Option synchronize should be enabled");
if (options.entities) throw new CronyxArgumentError("Option entities should not be passed");

const dataSource = new DataSource({ ...options, entities: [TypeormJobLockEntity], synchronize: true });
await dataSource.initialize();
Expand Down

0 comments on commit 279dca2

Please sign in to comment.