Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 104 improve error handling #105

Closed
wants to merge 10 commits into from
Closed

Conversation

stansv
Copy link
Contributor

@stansv stansv commented Jan 5, 2020

Fixed some cases when UnhandlerPromiseRejectionWarning's can appear, the simplest solution is to do console.log to handle rejections. Emitting error events in catch() sections would also produce UnhandlerPromiseRejectionWarning (it was surprising for me). Probably it'd be better to modify instance state (write error details into some field) and make all its methods non-functional by re-throwing that error in each call, but this is not very suitable for worker which can be used without calling any instance methods.

Also I've moved array of worker tokens to worker class field level, this can be helpful for monitoring.

Fixes #104

@stansv stansv changed the title [WIP] Fix 104 improve error handling Fix 104 improve error handling Jan 5, 2020
@stansv stansv requested a review from manast January 5, 2020 17:00
@dirkgroenen
Copy link

dirkgroenen commented Jan 14, 2020

Shouldn't the errors be emitted instead of logged, allowing end-users to catch them and act accordingly?

Something like this.run().catch(this.emit.bind(this)); instead of logging them on the console.

Copy link
Contributor

@manast manast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better as suggested in the comments to emit the errors instead of just logging them out

src/classes/queue-scheduler.ts Outdated Show resolved Hide resolved
src/classes/queue.ts Outdated Show resolved Hide resolved
src/classes/worker.ts Outdated Show resolved Hide resolved
src/classes/worker.ts Show resolved Hide resolved
@stansv stansv requested a review from manast January 15, 2020 07:58
@stansv
Copy link
Contributor Author

stansv commented Jan 15, 2020

Hi guys, yes I think suggested change is a good idea, but I'm not completely understand how to create an event listener for these errors.
PS I've also tried to do this.emit.bind(this)('error', error) before, but this event (error) causes UnhandlerPromiseRejectionWarning if no listeners attached..

@manast
Copy link
Contributor

manast commented Jan 20, 2020

@stansv are you sure about that? emitting an error thrown by a promise should avoid the warning you are mentioning.

@stansv
Copy link
Contributor Author

stansv commented Jan 27, 2020

@manast

import { EventEmitter } from 'events';

class Test extends EventEmitter {
  constructor() {
    super();
    Promise.reject(new Error('test')).catch(error => {
      this.emit('error', error);
    })
  }
}

(() => {
  new Test();
})();
$ ts-node src/index.ts
(node:15135) UnhandledPromiseRejectionWarning: Error: test
    at new Test (/Users/stansv/bullmq/src/index.ts:11:20)
    at /Users/stansv/bullmq/src/index.ts:18:3

(as I noted previously event name must be error to get this UnhandledPromiseRejectionWarning)

I feel I missing something about promises..

@ccollie
Copy link
Contributor

ccollie commented Jan 27, 2020

Could be node's scheduling of the catch. In many promise implementations it's delayed at least until the next tick of the event loop. In your case the end of the program may have been reached before the event fired.

@stansv
Copy link
Contributor Author

stansv commented Jan 27, 2020

No, I've found the reason — emit('error') itself throws an Error if there's no registered 'error' event listener (this is documented). Throwing in catch() block in turn causes UnhandledPromiseRejectionWarning.
The "correct" code would be

import { EventEmitter } from 'events';

class Test extends EventEmitter {
  constructor() {
    super();
    Promise.reject(new Error('test')).catch(error => {
      try {
        this.emit('error', error);
      } catch(_) {
        // ignore...
      }
    })
  }
}

(() => {
  new Test();
})();

@stansv
Copy link
Contributor Author

stansv commented Jan 29, 2020

@manast thanks for approval, but I cannot agree with current behavior, namely with

this.run().catch(this.emit.bind(this));

— if emit is called then first arg must be event name, not arbitrary error object; I do not understand how this might work (@dirkgroenen maybe you can help). How about this?

this.run().catch(error => {
      try {
        this.emit('error', error); // emit exactly 'error' event
      } catch(error) { // if 'error' event listener was not specially attached,
        console.log(error); // just print error to stdout
      }
    })

@dirkgroenen
Copy link

dirkgroenen commented Jan 29, 2020

— if emit is called then first arg must be event name, not arbitrary error object; I do not understand how this might work (@dirkgroenen maybe you can help). How about this?

You're right @stansv , I think I made a typo and was supposed to write this.run().catch(this.emit.bind(this, 'error'));

/ My two cents; you might want to consider logging the error with an additional message informing about the missing error handler?

@manast
Copy link
Contributor

manast commented Dec 30, 2020

Going to close this PR as master has drifted too much away from this branch and it is not easy to merge anymore.

@manast manast closed this Dec 30, 2020
@roggervalf roggervalf deleted the fix-104-improve-error-handling branch September 29, 2021 00:45
manast added a commit that referenced this pull request Mar 24, 2022
namoscato added a commit to namoscato/bullmq that referenced this pull request Mar 30, 2022
…-connection

* 'master' of github.com:taskforcesh/bullmq: (46 commits)
  GitBook: [taskforcesh#106] No subject
  docs(metrics): fix typo
  GitBook: [taskforcesh#105] No subject
  chore(release): 1.78.1 [skip ci]
  fix(queue): close repeat connection when calling close (taskforcesh#1154)
  chore(release): 1.78.0 [skip ci]
  feat(cron-parser): upgrades version to 4.2.1 (taskforcesh#1149) fixes taskforcesh#1147
  test(events): fix flaky test
  chore(release): 1.77.3 [skip ci]
  fix(async-send): check proc.send type (taskforcesh#1150)
  test(rate-limiter): fix flaky test
  chore(release): 1.77.2 [skip ci]
  perf(clean): speed up clean operation using deletion marker (taskforcesh#1144)
  fix(trim-events): consider maxLenEvents as 0 (taskforcesh#1137)
  chore(release): 1.77.1 [skip ci]
  fix(flow): remove processed children (taskforcesh#1060) fixes taskforcesh#1056
  chore(release): 1.77.0 [skip ci]
  feat: allow QueueScheduler to be extended
  chore(release): 1.76.6 [skip ci]
  fix(master): do not export master file (taskforcesh#1136) fixes taskforcesh#1125 ref taskforcesh#1129
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix UnhandledPromiseRejectionWarnings
4 participants