From 8f3237001468b791b48aeb2265d112a7d94fa14f Mon Sep 17 00:00:00 2001 From: Chris Anderson Date: Thu, 24 Jul 2025 13:38:00 -0500 Subject: [PATCH] fix: don't throw lock errors --- apps/platform/src/core/Lock.ts | 7 ++++++- apps/platform/src/queue/Job.ts | 7 ++++++- apps/platform/src/users/UserDeviceJob.ts | 17 +++++++++++++---- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/apps/platform/src/core/Lock.ts b/apps/platform/src/core/Lock.ts index b6d2ee42..2b9a1827 100644 --- a/apps/platform/src/core/Lock.ts +++ b/apps/platform/src/core/Lock.ts @@ -45,4 +45,9 @@ export const releaseLock = async (key: string) => { await App.main.redis.del(`lock:${key}`) } -export class LockError extends Error {} +export class LockError extends Error { + constructor(message: string) { + super(message) + this.name = 'LockError' + } +} diff --git a/apps/platform/src/queue/Job.ts b/apps/platform/src/queue/Job.ts index 504c3607..3f06a230 100644 --- a/apps/platform/src/queue/Job.ts +++ b/apps/platform/src/queue/Job.ts @@ -20,7 +20,12 @@ export interface EncodedJob { } export class JobError extends Error {} -export class RetryError extends JobError {} +export class RetryError extends JobError { + constructor(message: string) { + super(message) + this.name = 'RetryError' + } +} export const JobPriority = { none: 0, diff --git a/apps/platform/src/users/UserDeviceJob.ts b/apps/platform/src/users/UserDeviceJob.ts index 1fac0762..7d6ada30 100644 --- a/apps/platform/src/users/UserDeviceJob.ts +++ b/apps/platform/src/users/UserDeviceJob.ts @@ -1,6 +1,8 @@ -import { Job } from '../queue' +import { EncodedJob, Job } from '../queue' import { saveDevice } from './UserRepository' import { DeviceParams } from './Device' +import { LockError } from '../core/Lock' +import App from '../app' type UserDeviceTrigger = DeviceParams & { project_id: number @@ -13,13 +15,20 @@ export default class UserDeviceJob extends Job { return new this(data) } - static async handler({ project_id, ...device }: UserDeviceTrigger, job: UserDeviceJob) { - const attempts = job.options.attempts ?? 1 - const attemptsMade = job.state.attemptsMade ?? 0 + static async handler({ project_id, ...device }: UserDeviceTrigger, raw: EncodedJob) { + const attempts = raw.options.attempts ?? 1 + const attemptsMade = raw.state.attemptsMade ?? 0 try { await saveDevice(project_id, device) } catch (error) { + + // If record is locked, re-queue the job + if (error instanceof LockError) { + await App.main.queue.retry(raw) + throw error + } + if (attemptsMade < (attempts - 1)) throw error } }