Giter Site home page Giter Site logo

serenity-now's Introduction

serenity-now

Please handle your Promises' errors

SlideShare - http://mact.me/7j

Overview

I'm going to demonstrate a problem with the way Promises and Domains interact in Node.js.

  • A Promise is an object representing the eventual completion or failure of an asynchronous operation.
  • A Domain is a way to route errors and uncaught exceptions across multiple asynchronous operations to a single context. This allows you handle the error or exception without losing the context.

Should I even care about Domains?

Domains are deprecated. However, the replacement API has not been finalized. So if we want to take advantage of the features that Domains provide, we have no choice but to keep using them.

One popular web framework, Restify, has support for Domains built-in. Until very recently, this built-in support was inescapable. Although the latest versions of Restify v4 (v4.3.x) is allows you to opt-out, and as of v5, Domain support is actually opt-in, having no replacement for Domains means (in my opinion) that you should continue using Domains for the time being.

What's the problem?

You're probably using Promises. And people have been having problems with Promises and Domains in Node.js for a long time.

Part 1 - unhandled Promise rejection

Problem: unhandled Promise rejection will hang your web app.

Node 4

  • UnhandledPromiseRejectionWarning is not logged
  • server will hang

Node 6

  • UnhandledPromiseRejectionWarning is logged
  • server will hang

Node 8

  • UnhandledPromiseRejectionWarning is logged
  • additional DeprecationWarning is logged warning that in the future, Promise rejections that are not handled will terminate the Node.js process with a non-zero exit code
  • server will hang

Part 2 - Ok. Let's handle rejection.

Use .catch()

Problem: Your app will still hang.

Confused?

Ah. My bad. Use the error callback.

Problem: We have succeeded in not swallowing errors, but we're still not handling all the rejections. See Part 1.

Part 3 - Riiiiight. Let's handle the unhandled rejections. 🌀

Progress, but...

Problem: We have lost the Domain (and therefore the request and response). So, we can crash, but we cannot respond with a 500 error.

Part 4 - Bluebird to the rescue!

Success!

But, why?!

Native Promises and bluebird Promises are implemented differently.

  • Domains work as expected with bluebird Promises, which are userland code. But with native Promises, the active Domain has exited before the Promise rejection occurs.
  • nodejs/node-v0.x-archive#8648 (comment)

But throw?!

Restify's uncaughtException handler will catch the exception because it handles Domain errors.

Part 5 - Be more explicit.

Explicitly use the Domain the rejected Promise is connected to.

Part 6 - It's fixed in Node 8! 🎉

Native Promises and bluebird Promises interact with Domains the same way.

Coda

http://thecodebarbarian.com/unhandled-promise-rejections-in-node.js.html

serenity-now's People

Contributors

danmactough avatar

Stargazers

Sijie avatar Joe Van Drunen avatar

Watchers

 avatar James Cloos avatar

serenity-now's Issues

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.

Since we did not receive a CI status on the greenkeeper/initial branch, we assume that you still need to configure it.

If you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you don’t want it to run on every branch, you can whitelist branches starting with greenkeeper/.

We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

Once you have installed CI on this repository, you’ll need to re-trigger Greenkeeper’s initial Pull Request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper integration’s white list on Github. You'll find this list on your repo or organiszation’s settings page, under Installed GitHub Apps.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.