Domains - Express.js Guide: The Comprehensive Book on Express.js (2014)

Express.js Guide: The Comprehensive Book on Express.js (2014)

Domains

Contrary to its more popular homonym, domain is a core Node.js module. It aids developers in tracking and isolating errors that could be a juggernaut task. Think of domains as a smarter version of try/catch statements.

When it comes to Express.js, we can apply domains in error-prone routes. Before the routes, we need to define custom handlers to catch errors from domains:

1 var domain = require('domain');

2 var defaultHandler = express.errorHandler();

3 app.use(function (error, req, res, next) {

4 if (domain.active) {

5 console.info('caught with domain')

6 domain.active.emit("error", error);

7 } else {

8 console.info('no domain')

9 defaultHandler(error, req, res, next);

10 }

11 });

Here is a crashy route:

1 app.get("/e", function (req, res, next) {

2 var d = domain.create();

3 d.on("error", function (error) {

4 console.error(error.stack)

5 res.send(500, {"error": error.message});

6 });

7 d.run(function () {

8 //error prone code goes here

9 throw new Error("Database is down.");

10 });

11 });

On the other hand, we can call next with an error object (e.g., when an error variable comes from other nested calls):

1 app.get("/e", function (req, res, next) {

2 var d = domain.create();

3 d.on("error", function (error) {

4 console.error(error.stack)

5 res.send(500, {"error": error.message});

6 });

7 d.run(function () {

8 //error prone code goes here

9 next(new Error("Database is down."));

10 });

11 });

The working (or should we write crashing example) is in the expressjsguide/domains folder and on GitHub.

The full content of expressjsguide/domains/app.js:

1 /**

2 * Module dependencies.

3 */

4

5 var express = require('express');

6 var routes = require('./routes');

7 var user = require('./routes/user');

8 var http = require('http');

9 var path = require('path');

10

11 var app = express();

12

13 // all environments

14 app.set('port', process.env.PORT || 3000);

15 app.set('views', __dirname + '/views');

16 app.set('view engine', 'jade');

17 app.use(express.favicon());

18 app.use(express.logger('dev'));

19 app.use(express.bodyParser());

20 app.use(express.methodOverride());

21 app.use(app.router);

22 app.use(express.static(path.join(__dirname, 'public')));

23

24 var domain = require('domain');

25 var defaultHandler = express.errorHandler();

26 app.use(function (error, req, res, next) {

27 if (domain.active) {

28 console.info('caught with domain', domain.active);

29 domain.active.emit('error', error);

30 } else {

31 console.info('no domain');

32 defaultHandler(error, req, res, next);

33 }

34 });

35 app.get('/e', function (req, res, next) {

36 var d = domain.create();

37 d.on('error', function (error) {

38 console.error(error.stack);

39 res.send(500, {'error': error.message});

40 });

41 d.run(function () {

42 //error prone code goes here

43 throw new Error('Database is down.');

44 // next(new Error('Database is down.'));

45 });

46 });

47

48 app.get('/', routes.index);

49 app.get('/users', user.list);

50

51 http.createServer(app).listen(app.get('port'), function () {

52 console.log('Express server listening on port ' + app.get('port'));

53 });

For more ways to apply domains with Express.js, take a look at this amazing presentation.

Warning

Domain module is in experimental stage. This means that it’s likely that methods and behavior will change. Therefore, stay updated and use exact versions in the package.json file.