bullmq
bullmq copied to clipboard
[Bug]: Cannot read properties of undefined (reading 'forEach')
Version
v4.14.4
Platform
NodeJS
What happened?
In production (hosted on render.com), the job will get added to the queue, but the worker never runs. I am getting en error of Cannot read properties of undefined (reading 'forEach') from my QueueEvents listener. Locally, I have no issue. Been at this for days.
Other info: Node versions are the same, no other errors are being logged, and I can see each job get added to Redis.
How to reproduce.
Not sure if there is a way to reproduce since there seems to be no issue locally, and the issue only happens in production.
Relevant log output
Cannot read properties of undefined (reading 'forEach')
Code of Conduct
- [X] I agree to follow this project's Code of Conduct
hi @mieradi do you have any stacktrace of this error?
Besides the callstack it would be useful to see the actual code snippet where the exception is thrown, as it seems like it is coming from user code.
@roggervalf I will work on getting that!
@manast in regards to the code, I have removed all the code in my worker to make sure it works. Right now, it's just a log.
Here is an example
export const remindersQueue = new Queue('event-reminders', {
connection: {
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT as string),
maxRetriesPerRequest: null,
enableOfflineQueue: false,
retryStrategy: function (times: number) {
return Math.max(Math.min(Math.exp(times), 20000), 1000);
},
},
});
export async function handleEventReminders({
event,
timezone,
currentUser,
}: {
event: EventSchema;
parent_day_timezone: string;
currentUser: UserType;
}) {
// remove job from queue if it exists
const jobs = await eventRemindersQueue.getDelayed();
if (jobs) {
const jobToRemoveIndex = jobs.findIndex(
(job: any) => job.name === event.event_id
);
if (jobToRemoveIndex > -1) {
jobs[jobToRemoveIndex].remove();
}
}
const currentTime = utcToZonedTime(
new Date(),
parent_day_timezone || 'UTC'
).getTime();
const targetTime = utcToZonedTime(
event.start_time,
parent_day_timezone || 'UTC'
).getTime();
// if the event start time has already passed, don't add it to the queue
if (currentTime > targetTime || !parent_day_timezone) {
return;
}
eventRemindersQueue.add(
event.event_id as string,
{
event,
sender: currentUser.user_id,
},
{
delay: targetTime - currentTime - 1800000, // 30 minutes before event
}
);
}
my worker looks like this
export function eventReminderWorker() {
const worker = new Worker(
'event-reminders',
async (job) => {
console.log('EVENT REMINDER WORKER RUNNING');
},
{
connection: {
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT as string),
maxRetriesPerRequest: null,
retryStrategy: function (times: number) {
return Math.max(Math.min(Math.exp(times), 20000), 1000);
},
},
}
);
worker.on('completed', (job) => {
// console.log(`${job.id} has completed! at ${new Date()}`);
});
worker.on('failed', (job, err) => {
console.log({ EVENT_REMINDER_WORKER_ERROR: err });
console.log(`${job?.id} has failed with ${err.message}`);
});
process.on('SIGINT', async () => {
await worker.close();
});
}
So is the code above working or are you getting the error still? and do you have the complete error stack of the error?
@manast the code above works fine locally, but in prod the error I get is emitted from QueueEvents, and not from the worker. The worker never actually runs, which is the issue, and also is whats making this so hard to debug.
The error I get from queueEvents.on('failed'... is 3 has failed with reason Cannot read properties of undefined (reading 'forEach')
Here is what the server is logging:
Dec 5 06:48:43 PM event reminder worker started
Dec 5 06:50:00 PM A job with ID 3 is waiting
Dec 5 06:50:00 PM Job 3 is now active; previous status was waiting
Dec 5 06:50:00 PM 3 has failed with reason Cannot read properties of undefined (reading 'forEach')
Here is the QueueEvents code
const queueEvents = new QueueEvents('event-reminders', {
connection: {
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT as string),
},
});
queueEvents.on('completed', ({ jobId }) => {
console.log('done painting');
});
queueEvents.on(
'failed',
({ jobId, failedReason }: { jobId: string; failedReason: string }) => {
console.error('error painting', failedReason);
}
);
@manast any possible solutions on this?
Unfortunatelly there is not a lot information here for us to take any action...