bull icon indicating copy to clipboard operation
bull copied to clipboard

Unhandled promise rejections still occur

Open joakimbeng opened this issue 6 years ago • 13 comments

Description

The problem with unhandled promise rejections do still occur (see #1012).

Minimal, Working Test code to reproduce the issue.

Reproduced the issue in a separate repo: https://github.com/joakimbeng/bull-connection-problem

The code is essentially this:

'use strict';
const Queue = require('bull');

const queue = new Queue('my-queue');

queue.on('waiting', jobId => console.log('Job waiting', jobId));
queue.on('error', error => console.error('Queue Error', error));

queue.process(job => {
  console.log('processing job', job.id);
});

queue.add({some: 'data'});

process.on('unhandledRejection', error => {
  console.error('Unhandled Rejection', error);
  process.exit(1);
});

Bull version

v3.5.2

Additional information

The two function calls that are causing this is the this.setWorkerName() and utils.isRedisReady in commands/index.js. (utils.isRedisReady is the function that's actually causing the issue in this.setWorkerName as well).

Also, the problem only occurs after the queue.process function have been called, which the #1012 did not cover.

joakimbeng avatar Nov 28 '18 09:11 joakimbeng

I have a workaround for now (also in the linked repo above) but I don't think that's good enough or the right way to do it to make a PR for it

joakimbeng avatar Nov 28 '18 09:11 joakimbeng

This works for me.

//process queue 
bullQueue.isReady(()=>{
  bullQueue.process( (job='', jobDone) =>{
    console.log('Started Queues.');
    jobDone();
    // await processJobs(job, data);
  });
})

macpatel avatar Dec 13 '18 15:12 macpatel

@macpatel I cannot find isReady in the docs in https://github.com/OptimalBits/bull/blob/develop/REFERENCE.md, do you know why?

andresgariglio avatar Feb 28 '19 19:02 andresgariglio

@macpatel I cannot find isReady in the docs in https://github.com/OptimalBits/bull/blob/develop/REFERENCE.md, do you know why?

Don't remember how i ended up with this. Check this -> https://github.com/OptimalBits/bull/issues/567 https://github.com/OptimalBits/bull/search?q=isReady&unscoped_q=isReady

macpatel avatar Mar 01 '19 04:03 macpatel

Same here, calling Bull.process with a broken connection to Redis triggers an unhandled promise rejection.

Bull.isReady does the trick to catch the rejection though :

(async main() {
  const queue = new Bull('worker', { redis: '//localhost:22' });  // Impossible connection

  try {
    await queue.isReady() // rejects correctly (connect ECONNREFUSED 127.0.0.1:22)
    await queue.process(doSomething) // doesn't reject + unhandled promise rejection
  } catch (err) {
    // ...
  }
})()

I think this edge case is not a very rare one. Bull.process should reject.

I'd be happy to help if someone can point me in the right direction.

marcpicaud avatar Nov 05 '19 13:11 marcpicaud

To add to this, if you have an async event that throws an exception the promise is not caught.

const Bull = require('bull');
const queue = new Bull('worker', 'localhost');
queue.on('error', () => console.log('there was an error'));
queue.on('completed', async () => {
  throw new Error('test');
});
await queue.add({ foo: 'bar' });
await queue.process(() => console.log('completed'));

Gives me UnhandledPromiseRejectionWarning: Error: test

simontong avatar Nov 17 '19 07:11 simontong

@simontong That's a problem in your code. You have to handle any errors thrown by an event handler in application code. The event source (Bull in this case) can't be responsible for handling the error you throw in the handler.

zebulonj avatar Jan 10 '20 15:01 zebulonj

I am seeing unhandled promise rejections when I try to add a job to a queue with a bad connection (point being, this issue doesn't just manifest with a call to .process). There doesn't appear to be anywhere I can reliably trap and handle the error. I'm seeing the unhandled rejection error even when I have an error handler on the queue (queue.on('error', ...)). The error handler traps an error, but that error also bubbles up as an unhandled promise rejection.

zebulonj avatar Jan 10 '20 16:01 zebulonj

Same problem here about not being able to easily catch the connection errors. The only way seems to be:

try {
  await queue.isReady()
} catch (err) {
  // ...
}

Buts as @zebulonj says this isn't always convenient.

tombh avatar Feb 03 '20 09:02 tombh

I have the same issue, bull queues should provide a callback(or event) like

queue.onError(() => handle err)
queue.onReady(() => start processing)

kasvith avatar Mar 31 '20 15:03 kasvith

Is this still true as of v4.x of Bull? Also getting some random ERR_UNHANDLED_REJECTION from rejected promises, where it's crashing pods instead of marking the job as failed. Also using @nestjs/bull but it should be using this lib under the hood.

myknbani avatar Feb 13 '23 05:02 myknbani

@myknbani for better connection management I recommend you to use BullMQ if you can.

manast avatar Feb 13 '23 09:02 manast

Thanks @manast! I'll give Bull -> BullMQ a look

myknbani avatar Feb 16 '23 01:02 myknbani