Express: Looking for input Koa vs Express - Do not debate

Created on 26 Jun 2017  路  14Comments  路  Source: expressjs/express

Hi,

First, let's clarify that I'm not opening this to debate. I'm looking for answers, not arguments.
I started an app using Koa since I heard it has better error handling. But, Express 5 is in developement.

Will express 5 have error handling similar to Koa?
I don't want to spent most of my time putting error handlers everywhere.

Also, how good is the async/await support in express?

Thanks

question

Most helpful comment

Hi @Extarys , not using Koa day-to-day, I really don't know exactly how Koa's error handling is, so cannot easily comment on "Will express 5 have error handling similar to Koa?" since I don't have a clean understanding of (1) what it is and (2) what your specific idea of it is.

As for "Also, how good is the async/await support in express?", an async function is simply a function that will automatically be wrapped in a Promise by JavaScript, and there is absolutely plans to make Express 5 handle promises being returned by handlers / middleware, so I assume that is "good", though if you could provide some more detail on what exactly defines "good" support, I can probably provide some better answers.

I hope this helps and starts this off on a non-debate footing.

All 14 comments

Hi @Extarys , not using Koa day-to-day, I really don't know exactly how Koa's error handling is, so cannot easily comment on "Will express 5 have error handling similar to Koa?" since I don't have a clean understanding of (1) what it is and (2) what your specific idea of it is.

As for "Also, how good is the async/await support in express?", an async function is simply a function that will automatically be wrapped in a Promise by JavaScript, and there is absolutely plans to make Express 5 handle promises being returned by handlers / middleware, so I assume that is "good", though if you could provide some more detail on what exactly defines "good" support, I can probably provide some better answers.

I hope this helps and starts this off on a non-debate footing.

async/await is a new function of javascript .and will be supported on node.js v8

@jonathanong prob has an insightful opinion on this one.

@dougwilson what do you mean by

Express 5 handle promises being returned by handlers / middleware

Can you provide some pseudo-code example about this 馃槄 ?

Not to speak for @dougwilson , but this is the general idea @agauniyal ...

In Koa, the routers already know how to deal with promises and Koa will return status 500 on uncaught exceptions. With express, if you don't wrap your async handler similar to this, express would crash on uncaught exceptions. This is one of the reasons some of us just find Koa more convenient for writing modern async style code.

app.get('/', safeHandler(handler));

function safeHandler(handler) {
  return function(req, res) {
    handler(req, res).catch(error => res.status(500).send(error.message));
  };
}

async function handler(req, res) {
  await new Promise((resolve, reject) => reject(new Error('Hang!')));
  res.send('Hello, World!');
}

I've just started using async/await in my Express middleware, and have seen the "wrapper" solution as @lvpro offers above for capturing errors globally suggested in a variety of blog posts.

I too am wondering if there is a way to create a plugin for Express, or to handle those errors globally somehow without using the wrapper. Will Express 5 support this out of the box?

@adamreisnz there's been a ton of PRs and issues over the years for this but still nothing AFAIK :(

Instead of reimplementing the error handling, I would highly recommend delegating the error to express using the next function:

  function safeHandler(handler) {
-   return function(req, res) {
-     handler(req, res).catch(error => res.status(500).send(error.message));
+   return function(req, res, next) {
+     handler(req, res).catch(err => next(err));
    };
  }

This is my implementation;

'use strict';

/**
 * Helper middleware to wrap async functions
 */
module.exports = function wrapAsync(fn) {
  return function(req, res, next) {
    Promise
      .resolve(fn(req, res, next))
      .catch(error => next(error));
  };
};

Wrapping it in a promise resolve fixes the problem where your function does not return a promise, so it's also safe to use this wrapper with non-async functions.

Error handling is delegated to express.

@adamreisnz I would suggest a small change, to also capture if fn is throwing:

  module.exports = function wrapAsync(fn) {
    return function(req, res, next) {
-     Promise
-       .resolve(fn(req, res, next))
+     Promise.resolve()
+       .then(() => fn(req, res, next))
        .catch(error => next(error));
    };
  };

Good point, thanks 馃憤

I've also included a warning to make sure you pass in a function. Otherwise, if you accidentally pass in an undefined value (e.g. typo when referencing a middleware), the problem will be rather hard to debug;

'use strict';

/**
 * Helper middleware to wrap async functions
 */
module.exports = function wrapAsync(fn) {
  if (typeof fn !== 'function') {
    throw new Error('Not a function provided for wrapAsync');
  }
  return function(req, res, next) {
    Promise
      .resolve()
      .then(() => fn(req, res, next))
      .catch(error => next(error));
  };
};
  module.exports = function wrapAsync(fn) {
    if (typeof fn !== 'function') {
-     throw new Error('Not a function provided for wrapAsync');
+     throw new TypeError('Not a function provided for wrapAsync');
    }
    return function(req, res, next) {
      Promise
        .resolve()
        .then(() => fn(req, res, next))
        .catch(error => next(error));
    };
  };

You could also throw a TypeError instead of an error

The TypeError object represents an error when a value is not of the expected type.

I'm not sure if there is a purpose to keeping this issue open any more; if you feel otherwise, please let us know and we can re-open!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cuni0716 picture cuni0716  路  3Comments

despairblue picture despairblue  路  3Comments

ER-GAIBI picture ER-GAIBI  路  3Comments

Domiii picture Domiii  路  3Comments

extensionsapp picture extensionsapp  路  3Comments