SlideShare a Scribd company logo
Best Practices



Felix Geisendörfer           Munich Node.js User Group 01.12.2011 (v1)
(@)felixge(.de)

Twitter / GitHub / IRC


    Felix Geisendörfer
     (Berlin, Germany)
Callbacks
A terrible Example:

var fs = require('fs');

function readJSON(path, cb) {
  fs.readFile(path, 'utf8', function(err, data) {
    cb(JSON.parse(data));
  });
}
Error Delegation

var fs = require('fs');

function readJSON(path, cb) {
  fs.readFile(path, 'utf8', function(err, data) {
    if (err) return cb(err);

      cb(JSON.parse(data));
    });
}
Exception Handling
var fs = require('fs');

function readJSON(path, cb) {
  fs.readFile(path, 'utf8', function(err, data) {
    if (err) return cb(err);

      try {
        cb(JSON.parse(data));
      } catch (err) {
        cb(err);
      }
    });
}
Error parameter first
var fs = require('fs');

function readJSON(path, cb) {
  fs.readFile(path, 'utf8', function(err, data) {
    if (err) return cb(err);

      try {
        cb(null, JSON.parse(data));
      } catch (err) {
        cb(err);
      }
    });
}
Not your error
var fs = require('fs');

function readJSON(path, cb) {
  fs.readFile(path, 'utf8', function(err, data) {
    if (err) return cb(err);

      try {
        var json = JSON.parse(data);
      } catch (err) {
        return cb(err);
      }

      cb(null, json);
    });
}
Another common mistake
function readJSONFiles(files, cb) {
  var results   = {};
  var remaining = files.length;

    files.forEach(function(file) {
      readJSON(file, function(err, json) {
        if (err) return cb(err);

        results[file] = json;
        if (!--remaining) cb(null, results);
      });
    });
}
Only call back once
function readJSONFiles(files, cb) {
  var results   = {};
  var remaining = files.length;

    files.forEach(function(file) {
      readJSON(file, function(err, json) {
        if (err) {
          cb(err);
          cb = function() {};
          return;
        }

        results[file] = json;
        if (!--remaining) cb(null, results);
      });
    });
}
Nested Callbacks
db.query('SELECT A ...', function() {
  db.query('SELECT B ...', function() {
    db.query('SELECT C ...', function() {
      db.query('SELECT D ...', function() {
        db.query('SELECT E ...', function() {
          db.query('SELECT F ...', function() {
            db.query('SELECT G ...', function() {
              db.query('SELECT H ...', function() {
                db.query('SELECT I ...', function() {

                });
              });
            });
          });
        });
      });
    });
  });
});
Node.js  - Best practices
iPhone 4 owners?
You are holding it wrong!
Just kidding
Control Flow Libs
 var async = require('async');

 async.series({
   queryA: function(next) {
      db.query('SELECT A ...', next);
   },
   queryB: function(next) {
      db.query('SELECT A ...', next);
   },
   queryC: function(next) {
      db.query('SELECT A ...', next);
   }
   // ...
 }, function(err, results) {

 });
Split code into more
       methods
Maybe node.js is not a
 good tool for your
     problem?
Exceptions
(Dealing with Death)
Exceptions


throw new Error('oh no');




  Explicit, useful to crash your program
Exceptions
node.js:134
      throw e; // process.nextTick error, or 'error' event on first tick
      ^
Error: oh no
   at Object.<anonymous> (/Users/felix/explicit.js:1:69)
   at Module._compile (module.js:411:26)
   at Object..js (module.js:417:10)
   at Module.load (module.js:343:31)
   at Function._load (module.js:302:12)
   at Array.<anonymous> (module.js:430:10)
   at EventEmitter._tickCallback (node.js:126:26)


                        Output on stderr
Exceptions
function MyClass() {}

MyClass.prototype.myMethod = function() {
   setTimeout(function() {
     this.myOtherMethod();
   }, 10);
};

MyClass.prototype.myOtherMethod = function() {};

(new MyClass).myMethod();


        Implicit, usually undesirable / bugs
Exceptions

/Users/felix/implicit.js:5
  this.myOtherMethod();
      ^
TypeError: Object #<Object> has no method 'myOtherMethod'
  at Object._onTimeout (/Users/felix/implicit.js:5:10)
  at Timer.callback (timers.js:83:39)




                Incomplete stack trace : (
Global Catch


process.on('uncaughtException', function(err) {
  console.error('uncaught exception: ' + err.stack);
});
Please be careful
    with this!
Global catch gone wrong
// Deep inside the database driver you are using
cb(null, rows);

this._executeNextQueuedQuery();

// In your code
db.query('SELECT ...', function(err, rows) {
  console.log('First row: ' + row[0].id);
});
If you have to:

process.on('uncaughtException', function(err) {
  // You could use node-airbake for this
  sendErrorToLog(function() {
    // Once the error was logged, kill the process
    console.error(err.stack);
    process.exit(1);
  });
});
Even Better

       Processes die.

          Accept it.

Deal with it on a higher level.
Deployment
Novice


$ node server.js
Advanced Beginner


   $ node server.js &
Competent

$ screen
$ node server.js
Proficient

#!/bin/bash

while :
do
   node server.js
   echo "Server crashed!"
   sleep 1
done
Expert
#!upstart

description "myapp"
author      "felix"

start on (local-filesystems and net-device-up
IFACE=eth0)
stop on shutdown

respawn                # restart when job dies
respawn limit 5 60     # give up restart after 5
respawns in 60 seconds

script
  exec sudo -u www-data /path/to/server.js >> /
var/log/myapp.log 2>&1
end script
Innovation

$ git push joyent master
$ git push nodejitsu master
$ git push heroku master
Questions?




   @felixge
Thank you!

More Related Content

PDF
Node.js - A Quick Tour
PPT
Node js presentation
PDF
Nodejs Explained with Examples
PDF
Introduction to Nodejs
PPTX
introduction to node.js
KEY
A million connections and beyond - Node.js at scale
PPT
Building your first Node app with Connect & Express
PDF
Comet with node.js and V8
Node.js - A Quick Tour
Node js presentation
Nodejs Explained with Examples
Introduction to Nodejs
introduction to node.js
A million connections and beyond - Node.js at scale
Building your first Node app with Connect & Express
Comet with node.js and V8

What's hot (20)

PDF
Nodejs - A quick tour (v6)
KEY
NodeJS
KEY
Writing robust Node.js applications
PDF
KEY
Introduction to node.js
KEY
Building a real life application in node js
KEY
node.js: Javascript's in your backend
PPT
RESTful API In Node Js using Express
PDF
Node.js
PDF
NodeJS for Beginner
PDF
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
PDF
Non-blocking I/O, Event loops and node.js
PPT
JS everywhere 2011
PDF
Express node js
PDF
Node.js Event Loop & EventEmitter
PDF
Nodejs in Production
PPTX
Node.js Patterns for Discerning Developers
PDF
NodeJS
KEY
Streams are Awesome - (Node.js) TimesOpen Sep 2012
PDF
Beyond Phoenix
Nodejs - A quick tour (v6)
NodeJS
Writing robust Node.js applications
Introduction to node.js
Building a real life application in node js
node.js: Javascript's in your backend
RESTful API In Node Js using Express
Node.js
NodeJS for Beginner
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Non-blocking I/O, Event loops and node.js
JS everywhere 2011
Express node js
Node.js Event Loop & EventEmitter
Nodejs in Production
Node.js Patterns for Discerning Developers
NodeJS
Streams are Awesome - (Node.js) TimesOpen Sep 2012
Beyond Phoenix
Ad

Viewers also liked (20)

PDF
Anatomy of a Modern Node.js Application Architecture
PDF
Architecting large Node.js applications
PPTX
Introduction to Node.js
PDF
Modern UI Development With Node.js
PDF
The Enterprise Case for Node.js
PPTX
Introduction Node.js
PDF
Node Foundation Membership Overview 20160907
ODP
Node.js architecture (EN)
KEY
Node.js - As a networking tool
PPT
Scalability using Node.js
PDF
Асинхронность и параллелизм в Node.js
PPTX
Nodejs intro
KEY
Node.js - A practical introduction (v2)
PDF
Building servers with Node.js
PPT
Node.JS: возможности для РНР-разработчика
PDF
Building an alarm clock with node.js
PDF
Webconf nodejs-production-architecture
PPTX
NodeJS - Server Side JS
PPT
Nodejs Event Driven Concurrency for Web Applications
PDF
Node.js in production
Anatomy of a Modern Node.js Application Architecture
Architecting large Node.js applications
Introduction to Node.js
Modern UI Development With Node.js
The Enterprise Case for Node.js
Introduction Node.js
Node Foundation Membership Overview 20160907
Node.js architecture (EN)
Node.js - As a networking tool
Scalability using Node.js
Асинхронность и параллелизм в Node.js
Nodejs intro
Node.js - A practical introduction (v2)
Building servers with Node.js
Node.JS: возможности для РНР-разработчика
Building an alarm clock with node.js
Webconf nodejs-production-architecture
NodeJS - Server Side JS
Nodejs Event Driven Concurrency for Web Applications
Node.js in production
Ad

Similar to Node.js - Best practices (20)

PPTX
Avoiding Callback Hell with Async.js
PDF
Flow control in node.js
PDF
Node js
PDF
Promise: async programming hero
PDF
Kamil witecki asynchronous, yet readable, code
PDF
Asynchronous programming done right - Node.js
KEY
Playing With Fire - An Introduction to Node.js
PDF
NodeJS: the good parts? A skeptic’s view (jax jax2013)
PDF
To Err Is Human
PDF
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
PPTX
NodeJS
PDF
Common mistake in nodejs
PDF
Node.js - async for the rest of us.
KEY
How and why i roll my own node.js framework
PPTX
Promise it's partial
PDF
Matthew Eernisse, NodeJs, .toster {webdev}
PDF
Promises - Asynchronous Control Flow
PDF
Think Async: Asynchronous Patterns in NodeJS
PDF
Douglas Crockford: Serversideness
PDF
JS Fest 2019 Node.js Antipatterns
Avoiding Callback Hell with Async.js
Flow control in node.js
Node js
Promise: async programming hero
Kamil witecki asynchronous, yet readable, code
Asynchronous programming done right - Node.js
Playing With Fire - An Introduction to Node.js
NodeJS: the good parts? A skeptic’s view (jax jax2013)
To Err Is Human
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
NodeJS
Common mistake in nodejs
Node.js - async for the rest of us.
How and why i roll my own node.js framework
Promise it's partial
Matthew Eernisse, NodeJs, .toster {webdev}
Promises - Asynchronous Control Flow
Think Async: Asynchronous Patterns in NodeJS
Douglas Crockford: Serversideness
JS Fest 2019 Node.js Antipatterns

More from Felix Geisendörfer (11)

PDF
Nodejs a-practical-introduction-oredev
PDF
How to Test Asynchronous Code (v2)
PDF
How to Test Asynchronous Code
PDF
Nodejs - A quick tour (v5)
PDF
Nodejs - Should Ruby Developers Care?
PDF
Nodejs - A quick tour (v4)
PDF
Nodejs - A-quick-tour-v3
PDF
Dirty - How simple is your database?
PDF
Node.js - A Quick Tour II
PDF
With jQuery & CakePHP to World Domination
PDF
Nodejs a-practical-introduction-oredev
How to Test Asynchronous Code (v2)
How to Test Asynchronous Code
Nodejs - A quick tour (v5)
Nodejs - Should Ruby Developers Care?
Nodejs - A quick tour (v4)
Nodejs - A-quick-tour-v3
Dirty - How simple is your database?
Node.js - A Quick Tour II
With jQuery & CakePHP to World Domination

Recently uploaded (20)

PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PPTX
A Presentation on Artificial Intelligence
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
Cloud computing and distributed systems.
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Empathic Computing: Creating Shared Understanding
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Encapsulation theory and applications.pdf
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Spectral efficient network and resource selection model in 5G networks
Chapter 3 Spatial Domain Image Processing.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
A Presentation on Artificial Intelligence
Understanding_Digital_Forensics_Presentation.pptx
Cloud computing and distributed systems.
20250228 LYD VKU AI Blended-Learning.pptx
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Unlocking AI with Model Context Protocol (MCP)
Network Security Unit 5.pdf for BCA BBA.
Dropbox Q2 2025 Financial Results & Investor Presentation
The AUB Centre for AI in Media Proposal.docx
Empathic Computing: Creating Shared Understanding
Reach Out and Touch Someone: Haptics and Empathic Computing
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Agricultural_Statistics_at_a_Glance_2022_0.pdf
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Encapsulation theory and applications.pdf
CIFDAQ's Market Insight: SEC Turns Pro Crypto

Node.js - Best practices

  • 1. Best Practices Felix Geisendörfer Munich Node.js User Group 01.12.2011 (v1)
  • 2. (@)felixge(.de) Twitter / GitHub / IRC Felix Geisendörfer (Berlin, Germany)
  • 4. A terrible Example: var fs = require('fs'); function readJSON(path, cb) { fs.readFile(path, 'utf8', function(err, data) { cb(JSON.parse(data)); }); }
  • 5. Error Delegation var fs = require('fs'); function readJSON(path, cb) { fs.readFile(path, 'utf8', function(err, data) { if (err) return cb(err); cb(JSON.parse(data)); }); }
  • 6. Exception Handling var fs = require('fs'); function readJSON(path, cb) { fs.readFile(path, 'utf8', function(err, data) { if (err) return cb(err); try { cb(JSON.parse(data)); } catch (err) { cb(err); } }); }
  • 7. Error parameter first var fs = require('fs'); function readJSON(path, cb) { fs.readFile(path, 'utf8', function(err, data) { if (err) return cb(err); try { cb(null, JSON.parse(data)); } catch (err) { cb(err); } }); }
  • 8. Not your error var fs = require('fs'); function readJSON(path, cb) { fs.readFile(path, 'utf8', function(err, data) { if (err) return cb(err); try { var json = JSON.parse(data); } catch (err) { return cb(err); } cb(null, json); }); }
  • 9. Another common mistake function readJSONFiles(files, cb) { var results = {}; var remaining = files.length; files.forEach(function(file) { readJSON(file, function(err, json) { if (err) return cb(err); results[file] = json; if (!--remaining) cb(null, results); }); }); }
  • 10. Only call back once function readJSONFiles(files, cb) { var results = {}; var remaining = files.length; files.forEach(function(file) { readJSON(file, function(err, json) { if (err) { cb(err); cb = function() {}; return; } results[file] = json; if (!--remaining) cb(null, results); }); }); }
  • 12. db.query('SELECT A ...', function() { db.query('SELECT B ...', function() { db.query('SELECT C ...', function() { db.query('SELECT D ...', function() { db.query('SELECT E ...', function() { db.query('SELECT F ...', function() { db.query('SELECT G ...', function() { db.query('SELECT H ...', function() { db.query('SELECT I ...', function() { }); }); }); }); }); }); }); }); });
  • 15. You are holding it wrong!
  • 17. Control Flow Libs var async = require('async'); async.series({ queryA: function(next) { db.query('SELECT A ...', next); }, queryB: function(next) { db.query('SELECT A ...', next); }, queryC: function(next) { db.query('SELECT A ...', next); } // ... }, function(err, results) { });
  • 18. Split code into more methods
  • 19. Maybe node.js is not a good tool for your problem?
  • 21. Exceptions throw new Error('oh no'); Explicit, useful to crash your program
  • 22. Exceptions node.js:134 throw e; // process.nextTick error, or 'error' event on first tick ^ Error: oh no at Object.<anonymous> (/Users/felix/explicit.js:1:69) at Module._compile (module.js:411:26) at Object..js (module.js:417:10) at Module.load (module.js:343:31) at Function._load (module.js:302:12) at Array.<anonymous> (module.js:430:10) at EventEmitter._tickCallback (node.js:126:26) Output on stderr
  • 23. Exceptions function MyClass() {} MyClass.prototype.myMethod = function() { setTimeout(function() { this.myOtherMethod(); }, 10); }; MyClass.prototype.myOtherMethod = function() {}; (new MyClass).myMethod(); Implicit, usually undesirable / bugs
  • 24. Exceptions /Users/felix/implicit.js:5 this.myOtherMethod(); ^ TypeError: Object #<Object> has no method 'myOtherMethod' at Object._onTimeout (/Users/felix/implicit.js:5:10) at Timer.callback (timers.js:83:39) Incomplete stack trace : (
  • 25. Global Catch process.on('uncaughtException', function(err) { console.error('uncaught exception: ' + err.stack); });
  • 26. Please be careful with this!
  • 27. Global catch gone wrong // Deep inside the database driver you are using cb(null, rows); this._executeNextQueuedQuery(); // In your code db.query('SELECT ...', function(err, rows) { console.log('First row: ' + row[0].id); });
  • 28. If you have to: process.on('uncaughtException', function(err) { // You could use node-airbake for this sendErrorToLog(function() { // Once the error was logged, kill the process console.error(err.stack); process.exit(1); }); });
  • 29. Even Better Processes die. Accept it. Deal with it on a higher level.
  • 32. Advanced Beginner $ node server.js &
  • 34. Proficient #!/bin/bash while : do node server.js echo "Server crashed!" sleep 1 done
  • 35. Expert #!upstart description "myapp" author "felix" start on (local-filesystems and net-device-up IFACE=eth0) stop on shutdown respawn # restart when job dies respawn limit 5 60 # give up restart after 5 respawns in 60 seconds script exec sudo -u www-data /path/to/server.js >> / var/log/myapp.log 2>&1 end script
  • 36. Innovation $ git push joyent master $ git push nodejitsu master $ git push heroku master
  • 37. Questions? @felixge

Editor's Notes

  • #2: \n
  • #3: \n
  • #4: \n
  • #5: If you&amp;#x2019;re function works like this, I will not use it\n
  • #6: Otherwise JSON.parse(undefined) -&gt; SyntaxError: Unexpected token ILLEGAL \n
  • #7: Otherwise invalid JSON -&gt; SyntaxError: Unexpected token ILLEGAL\n
  • #8: Otherwise I always have to -&gt; if (json instanceof Error) ...\n
  • #9: Subtle: Do not catch errors inside your callback -&gt; very unexpected results\n
  • #10: \n
  • #11: \n
  • #12: \n
  • #13: \n
  • #14: \n
  • #15: \n
  • #16: Fake photograph btw.: http://www.snopes.com/photos/politics/bushbook.asp\n
  • #17: Nested callbacks are an actual concern in the node community\n
  • #18: \n
  • #19: \n
  • #20: \n
  • #21: \n
  • #22: Please DO NOT EVER use exceptions for control flow.\n\nLike so many things in JS, JSON.parse() throwing exceptions is bullshit.\n
  • #23: \n
  • #24: \n
  • #25: \n
  • #26: Also known as Stage 3 / Bargaining stage in K&amp;#xFC;bler-Ross model of &amp;#x201C;The Five Stages of Grief&amp;#x201D;\n
  • #27: \n
  • #28: If rows.length === 0 the exception triggered from accessing rows[0].id will STALL your database driver. Not good!\n
  • #29: \n
  • #30: Higher level could be upstart / monit / etc.\n
  • #31: \n
  • #32: \n
  • #33: \n
  • #34: \n
  • #35: \n
  • #36: \n
  • #37: \n
  • #38: \n
  • #39: \n