SlideShare a Scribd company logo
Defensive Programming
in Javascript & node.js
Wednesday, May 29, 13
INTRODUCTION
Ruben Tan Long Zheng 陈龙正
VP of Engineering, OnApp CDN KL
Lead Engineer, 40 Square Sdn Bhd
Javascript > 5 years
@roguejs
Organizer of Nodehack KL
Wednesday, May 29, 13
OVERVIEW
Dependency Awareness
Javascript Mastery
Methodology Improvements
Wednesday, May 29, 13
SEASON 1
DEPENDENCY
AWARENESS
Wednesday, May 29, 13
Internal dependencies
Libraries
require(), include()
External dependencies
Services, files, databases, etc
socket.connect(), db.open()
DEPENDENCY TYPES
Wednesday, May 29, 13
NEVER ASSUME!
Never assume a dependency is reliable!
var db = require(‘database’);
db.open();
db.write(‘foo bar’, function (err, data) {
// ... do something ...
});
Wednesday, May 29, 13
NEVER ASSUME!
var db = require(‘database’);
db.open();
db.write(‘foo bar’, function (err, data) {
// ... do something ...
});
What if this failed?
will write() throw an error? will open() throw
an exception?
Wednesday, May 29, 13
NEVER ASSUME!
var db = require(‘database’);
db.open(function (err) {
db.write(‘mr-big’, bigData, function (err, data) {
// ... unrelated logic
db.close();
});
db.read(‘foo2’, function (err, data) {
// ... some work done
});
});
Accidents happen...
Wednesday, May 29, 13
NEVER ASSUME!
var db = require(‘database’);
db.open(function (err) {
db.write(‘mr-big’, bigData, function (err, data) {
// ... unrelated logic
db.close();
});
db.read(‘foo2’, function (err, data) {
// ... some work done
});
});
close() might affect read()
Wednesday, May 29, 13
A MORE COMPLEX EXAMPLE...
Wednesday, May 29, 13
VIDEO STREAMING SERVICE
Video
Streamer
Origin
Stats
Logger
VOD
Client
User
Accounting
UploadLive
Client
User
Stream
Stream
LogReport
Render
Render
Wednesday, May 29, 13
VIDEO STREAMING SERVICE
Video
Streamer
Origin
Stats
Logger
VOD
Client
User
Accounting
UploadLive
Client
User
Stream
Stream
LogReport
Render
Render
1
2
3
4
5
6
7
8
9
10
11
Wednesday, May 29, 13
DEPENDENCY AWARENESS
What can fail, WILL FAIL!
Never assume a dependency is reliable!
Contingency plans - failover, redundancy, fail-fast, etc
Pro-active monitoring
Load test, stress test, chaos monkey, etc
Remember, what can fail, WILL FAIL!
Wednesday, May 29, 13
SEASON 2
JAVASCRIPT MASTERY
Wednesday, May 29, 13
JAVASCRIPT MASTERY
Code Execution Order
Sanitization & Validation
Scope
Control Flow
Wednesday, May 29, 13
I KNOW CODE-FU!
Wednesday, May 29, 13
EXECUTION ORDER
var mq = require(‘mq’);
mq.conn(...);
mq.on(‘ready’, function () {
mq.send(‘batman’);
mq.on(‘message’, function (msg) {
console.log(msg);
mq.close();
});
});
mq is never closed!
send() executes before on()
Wednesday, May 29, 13
DOIN’ IT RIGHT!
var mq = require(‘mq’);
mq.conn(...);
mq.on(‘ready’, function () {
mq.on(‘message’, function (msg) {
console.log(msg);
mq.close();
});
mq.send(‘batman’);
});
Swap places
Wednesday, May 29, 13
SANITIZATION & VALIDATION
function foodForKittens(num) {
return num * 10;
}
foodForKittens();
num is not validated, is undefined
this will fail!
Wednesday, May 29, 13
TOO SIMPLE?
Wednesday, May 29, 13
SANITIZATION & VALIDATION
var db = require(‘database’);
var conn = db.open(...);
function writeToDb(conn, cb) {
conn.write(bigData, function (err, res) {
if (err) {
cb(err);
return;
}
cb(null, res);
});
});
writeToDb(conn, ghostCallback);
Wednesday, May 29, 13
Wednesday, May 29, 13
var db = require(‘database’);
var conn = db.open(...);
function writeToDb(conn, cb) {
conn.write(bigData, function (err, res) {
if (err) {
cb(err);
return;
}
cb(null, res);
});
});
writeToDb(conn, ghostCallback);
what if open() returned undefined?
this will throw an exception!
Wednesday, May 29, 13
var db = require(‘database’);
var conn = db.open(...);
function writeToDb(conn, cb) {
conn.write(bigData, function (err, res) {
if (err) {
cb(err);
return;
}
cb(null, res);
});
});
writeToDb(conn, ghostCallback);
What if ghostCallback is undefined?
These will fail too!
Wednesday, May 29, 13
DOIN’ IT RIGHT!
var db = require(‘database’);
var conn = db.open(...);
function writeToDb(conn, cb) {
if (typeof conn !== ‘object’) {
// ... handle error ...
}
if (typeof cb !== ‘function’) {
// ... handle error ...
}
conn.write(bigData, function (err, res) {
if (err) {
cb(err);
return;
}
cb(null, res);
});
});
writeToDb(conn, ghostCallback);
Validate your input,
especially when they
involve functions or
methods that you need to
invoke in your code.
These are not the time to
fail-fast!
Wednesday, May 29, 13
DON’T GO OVERBOARD...
Validate only necessary parameters
Method invocations (anObject.method())
Function invocations (aFunction())
Have a proper error/exception handling policy
Validate for correctness, not existence
Correctness: typeof a === ‘object’
Existence: a !== undefined
Wednesday, May 29, 13
SCOPE AWARENESS
Plagues most callback-based code
Bad practice leads to costly debugging waste
New JS programmers not aware of scoping
JS scoping is a simple but weird thing (to non-JS
programmers)
Wednesday, May 29, 13
SCOPE!!!
var a = ‘outside’;
if (true) {
var a = ‘inside’;
console.log(a);
}
console.log(a);
What is the output?
> node test.js
inside
inside
Wednesday, May 29, 13
SCOPE!!!
Non-JS programmers:
a inside the if block is “inside”
a outside the if block is “outside”
JS programmers:
they are both “inside”
JS scope by function
Wednesday, May 29, 13
SCOPE CHAINS!!!
var avar = 1;
(function outer1() {
var avar = 2;
(function inner1() {
var avar = 3;
console.log(avar); // outputs 3
})();
(function inner2() {
console.log(avar); // outputs 2
})();
})();
(function outer2() {
(function inner3() {
console.log(avar); // outputs 1
})();
})();
inner1()
local - found!
inner2()
local - nope
outer1() - found!
inner3()
local - nope
outer2() - nope
global - found!
Wednesday, May 29, 13
HOISTING VARIABLES
function () {
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
// ... do something
}
}
}
function () {
var i, j; // now the scope is clear for i & j
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
// ... do something
}
}
}
Below is far clearer what individual variable scopes are:
Wednesday, May 29, 13
CONTROL FLOW
Node.js’ async nature makes it unintuitive to predict
control flow
I <3 async (github.com/caolan/async)
Control flow is ugly. Welcome to Javascript.
Async will save your life. Use it.
Wednesday, May 29, 13
CONTROL FLOW
var fs;
fs = require(‘fs’);
fs.readFile(‘./myfile.txt’, function (err, data) {
if (err) {
console.log(err);
return;
}
fs.writeFile(‘./myfile2.txt’, data, function (err) {
if (err) {
console.log(err);
return;
}
// ... do stuff ...
});
})
Wednesday, May 29, 13
CONTROL FLOW
Callback hell!
Step 1
Step 2
Step 3
Step 4
Step 5
Wednesday, May 29, 13
mod.step1(function () {
mod.step2(function () {
mod.step3(function () {
mod.step4(function () {
mod.step5(function () {
// ... too many levels ...
});
});
}
});
});
Wednesday, May 29, 13
CONTROL FLOW
var async, fs;
async = require(‘async’);
fs = require(‘fs’);
async.waterfall([
function step1(callback) {
fs.readFile(‘./myfile.txt’, callback);
},
function step2(data, callback) {
fs.writeFile(‘./myfile2.txt’, data, callback);
}
], function (err) {
// ... execute something in the end ...
});
Wednesday, May 29, 13
SEASON 3
METHODOLOGY
IMPROVEMENTS
Wednesday, May 29, 13
GOLDEN RULES
Golden Rules of Defensive Programming
Proper error handling policy
Intelligent logging
Design for failure
Wednesday, May 29, 13
ERROR HANDLING
Never, ever HIDE errors
> node app.js 2>&1 /dev/null
ob.callback(function (err, data) {
if (err) {}
console.log(data);
});
socket.on(‘error’, function () {});
Wednesday, May 29, 13
ERROR HANDLING
I WILL FIND YOU
AND I WILL CRASH YOU
Wednesday, May 29, 13
ERROR HANDLING
Standardize error handling in the app
Log to error DB
Output to error file
Output error to a stream
Use a logging library
Ask a leprechaun to manage it
etc
Wednesday, May 29, 13
LOGGING
How do you feel if your “log” looks like this?
> tail -f error.log
[12:01:55] ERROR - General error detected
[12:01:56] ERROR - General error detected
[12:01:57] ERROR - General error detected
[12:01:58] ERROR - General error detected
[12:01:59] ERROR - General error detected
[12:02:00] ERROR - General error detected
[12:02:01] ERROR - General error detected
Wednesday, May 29, 13
LOGGING
Wednesday, May 29, 13
LOGGING
Logs are the first place you go to find out what
happened
Standardize a log location for each app
Make logs easy to access for developers
Wednesday, May 29, 13
DESIGN FOR FAILURE
Common steps to designing software:
1 - what should it do?
2 - how do I do it?
3 - how do I deploy?
4 - done
Wednesday, May 29, 13
DESIGN FOR FAILURE
Proper steps in defensive programming:
1 - what should it do?
2 - how many ways can it fail?
3 - how do I know when it fails?
4 - how do I prevent it from failing?
5 - write code accordingly
Wednesday, May 29, 13
DESIGN FOR FAILURE
Nothing is reliable
TCP can fail
Network can go down
Servers can run out of memory
Cows might fly through the sky crashing into your
datacenter and flooding the server rooms with milk
and destroying everything
Wednesday, May 29, 13
DESIGN FOR FAILURE
Designing for failure mindset & methodologies:
Identify SPOF (single point of failures)
Redundancy, failover, monitoring
Fail-fast, start-fast
Persist important data
Reliability & Consistency > Speed
Code is liability
Wednesday, May 29, 13
~ The End ~
Wednesday, May 29, 13

More Related Content

What's hot (11)

PDF
Closures for Java
nextlib
 
ODP
Beyond PHP - it's not (just) about the code
Wim Godden
 
PDF
Realizando Pruebas con Spock
Andres Almiray
 
PDF
Coffeescript - Getting Started
JeongHun Byeon
 
PDF
Smolder @Silex
Jeen Lee
 
PDF
Modern Getopt for Command Line Processing in Perl
Nova Patch
 
PDF
GoCracow #5 Bartlomiej klimczak - GoBDD
Bartłomiej Kiełbasa
 
PDF
PuppetConf 2016: Puppet Troubleshooting – Thomas Uphill, Wells Fargo
Puppet
 
PDF
Writing Modular Command-line Apps with App::Cmd
Ricardo Signes
 
PPTX
Tokyo APAC Groundbreakers tour - The Complete Java Developer
Connor McDonald
 
PDF
Feb14 successful development
Connor McDonald
 
Closures for Java
nextlib
 
Beyond PHP - it's not (just) about the code
Wim Godden
 
Realizando Pruebas con Spock
Andres Almiray
 
Coffeescript - Getting Started
JeongHun Byeon
 
Smolder @Silex
Jeen Lee
 
Modern Getopt for Command Line Processing in Perl
Nova Patch
 
GoCracow #5 Bartlomiej klimczak - GoBDD
Bartłomiej Kiełbasa
 
PuppetConf 2016: Puppet Troubleshooting – Thomas Uphill, Wells Fargo
Puppet
 
Writing Modular Command-line Apps with App::Cmd
Ricardo Signes
 
Tokyo APAC Groundbreakers tour - The Complete Java Developer
Connor McDonald
 
Feb14 successful development
Connor McDonald
 

Viewers also liked (16)

PPTX
Blood and its importance
Kanishkavikram Purohit
 
PPTX
Protection
Roger Watson
 
PPTX
Blood Coagulation, its Mechanism Disorders and its role in Human Life
Fiverr (Fiverr.com)
 
PPT
The Blood Cell, Immunity and blood coagulation
nilofer24
 
PPTX
Hematology: Blood coagulation
ProtegeNithi
 
PPT
Mechanism of blood coagulation /certified fixed orthodontic courses by Indian...
Indian dental academy
 
PPTX
Coagulation cascade
niraj phoju
 
PPTX
Hemostasis and blood coagulation general pathology
Siganga Siganga
 
ODP
Node.js security
Maciej Lasyk
 
PPT
blood clotting
Hina Yaseen Ranjha
 
PPT
Coagulation
shabeel pn
 
PPTX
Blood Physiology - Ppt
PEER FATHIMA BARAKATHU
 
PDF
AngularJS Security: defend your Single Page Application
Carlo Bonamico
 
PPTX
Blood physiology
Raniagaye Mansibang
 
PPTX
Blood coagulation
GunJee Gj
 
PPTX
Blood and blood transfusions
shalinisinghchauhan
 
Blood and its importance
Kanishkavikram Purohit
 
Protection
Roger Watson
 
Blood Coagulation, its Mechanism Disorders and its role in Human Life
Fiverr (Fiverr.com)
 
The Blood Cell, Immunity and blood coagulation
nilofer24
 
Hematology: Blood coagulation
ProtegeNithi
 
Mechanism of blood coagulation /certified fixed orthodontic courses by Indian...
Indian dental academy
 
Coagulation cascade
niraj phoju
 
Hemostasis and blood coagulation general pathology
Siganga Siganga
 
Node.js security
Maciej Lasyk
 
blood clotting
Hina Yaseen Ranjha
 
Coagulation
shabeel pn
 
Blood Physiology - Ppt
PEER FATHIMA BARAKATHU
 
AngularJS Security: defend your Single Page Application
Carlo Bonamico
 
Blood physiology
Raniagaye Mansibang
 
Blood coagulation
GunJee Gj
 
Blood and blood transfusions
shalinisinghchauhan
 
Ad

Similar to Defensive programming in Javascript and Node.js (20)

PDF
Put on Your Asynchronous Hat and Node
Marc Fasel
 
PDF
JavaScript for impatient programmers.pdf
JoaqunFerrariIlusus
 
PPTX
Hands On Intro to Node.js
Chris Cowan
 
PDF
NodeJS: the good parts? A skeptic’s view (jax jax2013)
Chris Richardson
 
PDF
Practical pairing of generative programming with functional programming.
Eugene Lazutkin
 
PDF
To Err Is Human
Alex Liu
 
PDF
Perfomatix - NodeJS Coding Standards
Perfomatix Solutions
 
KEY
Node.js basics
Ben Lin
 
PPTX
Requiring your own files.pptx
Lovely Professional University
 
PDF
540slidesofnodejsbackendhopeitworkforu.pdf
hamzadamani7
 
PDF
Scalable JavaScript
Ynon Perek
 
PPTX
Functional Programming in Javascript - IL Tech Talks week
yoavrubin
 
PDF
ES6: The Awesome Parts
Domenic Denicola
 
PPTX
Use Promises, Futures and some functional programing stuff without being a ma...
Quentin Adam
 
PDF
Refactoring JavaScript turning bad code into good code First Edition Burchard
simbajdzikie4
 
PDF
Node.js Patterns and Opinions
IsaacSchlueter
 
PPTX
Intro To Node.js
Chris Cowan
 
PDF
SNP STEAM Academy 2017 Class #12
Markus Van Kempen
 
PDF
NodeJS: the good parts? A skeptic’s view (jmaghreb, jmaghreb2013)
Chris Richardson
 
PDF
Practical JavaScript Programming - Session 8/8
Wilson Su
 
Put on Your Asynchronous Hat and Node
Marc Fasel
 
JavaScript for impatient programmers.pdf
JoaqunFerrariIlusus
 
Hands On Intro to Node.js
Chris Cowan
 
NodeJS: the good parts? A skeptic’s view (jax jax2013)
Chris Richardson
 
Practical pairing of generative programming with functional programming.
Eugene Lazutkin
 
To Err Is Human
Alex Liu
 
Perfomatix - NodeJS Coding Standards
Perfomatix Solutions
 
Node.js basics
Ben Lin
 
Requiring your own files.pptx
Lovely Professional University
 
540slidesofnodejsbackendhopeitworkforu.pdf
hamzadamani7
 
Scalable JavaScript
Ynon Perek
 
Functional Programming in Javascript - IL Tech Talks week
yoavrubin
 
ES6: The Awesome Parts
Domenic Denicola
 
Use Promises, Futures and some functional programing stuff without being a ma...
Quentin Adam
 
Refactoring JavaScript turning bad code into good code First Edition Burchard
simbajdzikie4
 
Node.js Patterns and Opinions
IsaacSchlueter
 
Intro To Node.js
Chris Cowan
 
SNP STEAM Academy 2017 Class #12
Markus Van Kempen
 
NodeJS: the good parts? A skeptic’s view (jmaghreb, jmaghreb2013)
Chris Richardson
 
Practical JavaScript Programming - Session 8/8
Wilson Su
 
Ad

More from Ruben Tan (11)

PDF
Basic distributed systems principles
Ruben Tan
 
PDF
Demystifying blockchains
Ruben Tan
 
PDF
Banking on blockchains
Ruben Tan
 
PDF
Consensus in distributed computing
Ruben Tan
 
PPT
Leveraging zeromq for node.js
Ruben Tan
 
PDF
Client-side storage
Ruben Tan
 
KEY
Distributed app development with nodejs and zeromq
Ruben Tan
 
KEY
How we git - commit policy and code review
Ruben Tan
 
KEY
NodeHack #2 - MVP
Ruben Tan
 
KEY
40 square's git workflow
Ruben Tan
 
KEY
Unit testing for 40 square software
Ruben Tan
 
Basic distributed systems principles
Ruben Tan
 
Demystifying blockchains
Ruben Tan
 
Banking on blockchains
Ruben Tan
 
Consensus in distributed computing
Ruben Tan
 
Leveraging zeromq for node.js
Ruben Tan
 
Client-side storage
Ruben Tan
 
Distributed app development with nodejs and zeromq
Ruben Tan
 
How we git - commit policy and code review
Ruben Tan
 
NodeHack #2 - MVP
Ruben Tan
 
40 square's git workflow
Ruben Tan
 
Unit testing for 40 square software
Ruben Tan
 

Recently uploaded (20)

PPTX
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Poster...
Michele Kryston
 
PDF
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
PPTX
01_Approach Cyber- DORA Incident Management.pptx
FinTech Belgium
 
PPTX
Paycifi - Programmable Trust_Breakfast_PPTXT
FinTech Belgium
 
PPTX
Smarter Governance with AI: What Every Board Needs to Know
OnBoard
 
PDF
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
Edge AI and Vision Alliance
 
PPTX
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
PDF
Database Benchmarking for Performance Masterclass: Session 1 - Benchmarking F...
ScyllaDB
 
PDF
Automating the Geo-Referencing of Historic Aerial Photography in Flanders
Safe Software
 
PPTX
Enabling the Digital Artisan – keynote at ICOCI 2025
Alan Dix
 
PDF
Darley - FIRST Copenhagen Lightning Talk (2025-06-26) Epochalypse 2038 - Time...
treyka
 
PDF
The Growing Value and Application of FME & GenAI
Safe Software
 
PPTX
reInforce 2025 Lightning Talk - Scott Francis.pptx
ScottFrancis51
 
PPTX
Practical Applications of AI in Local Government
OnBoard
 
PDF
Open Source Milvus Vector Database v 2.6
Zilliz
 
PDF
UiPath Agentic AI ile Akıllı Otomasyonun Yeni Çağı
UiPathCommunity
 
DOCX
Daily Lesson Log MATATAG ICT TEchnology 8
LOIDAALMAZAN3
 
PDF
5 Things to Consider When Deploying AI in Your Enterprise
Safe Software
 
PDF
Java 25 and Beyond - A Roadmap of Innovations
Ana-Maria Mihalceanu
 
PDF
Unlocking FME Flow’s Potential: Architecture Design for Modern Enterprises
Safe Software
 
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Poster...
Michele Kryston
 
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
01_Approach Cyber- DORA Incident Management.pptx
FinTech Belgium
 
Paycifi - Programmable Trust_Breakfast_PPTXT
FinTech Belgium
 
Smarter Governance with AI: What Every Board Needs to Know
OnBoard
 
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
Edge AI and Vision Alliance
 
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
Database Benchmarking for Performance Masterclass: Session 1 - Benchmarking F...
ScyllaDB
 
Automating the Geo-Referencing of Historic Aerial Photography in Flanders
Safe Software
 
Enabling the Digital Artisan – keynote at ICOCI 2025
Alan Dix
 
Darley - FIRST Copenhagen Lightning Talk (2025-06-26) Epochalypse 2038 - Time...
treyka
 
The Growing Value and Application of FME & GenAI
Safe Software
 
reInforce 2025 Lightning Talk - Scott Francis.pptx
ScottFrancis51
 
Practical Applications of AI in Local Government
OnBoard
 
Open Source Milvus Vector Database v 2.6
Zilliz
 
UiPath Agentic AI ile Akıllı Otomasyonun Yeni Çağı
UiPathCommunity
 
Daily Lesson Log MATATAG ICT TEchnology 8
LOIDAALMAZAN3
 
5 Things to Consider When Deploying AI in Your Enterprise
Safe Software
 
Java 25 and Beyond - A Roadmap of Innovations
Ana-Maria Mihalceanu
 
Unlocking FME Flow’s Potential: Architecture Design for Modern Enterprises
Safe Software
 

Defensive programming in Javascript and Node.js

  • 1. Defensive Programming in Javascript & node.js Wednesday, May 29, 13
  • 2. INTRODUCTION Ruben Tan Long Zheng 陈龙正 VP of Engineering, OnApp CDN KL Lead Engineer, 40 Square Sdn Bhd Javascript > 5 years @roguejs Organizer of Nodehack KL Wednesday, May 29, 13
  • 5. Internal dependencies Libraries require(), include() External dependencies Services, files, databases, etc socket.connect(), db.open() DEPENDENCY TYPES Wednesday, May 29, 13
  • 6. NEVER ASSUME! Never assume a dependency is reliable! var db = require(‘database’); db.open(); db.write(‘foo bar’, function (err, data) { // ... do something ... }); Wednesday, May 29, 13
  • 7. NEVER ASSUME! var db = require(‘database’); db.open(); db.write(‘foo bar’, function (err, data) { // ... do something ... }); What if this failed? will write() throw an error? will open() throw an exception? Wednesday, May 29, 13
  • 8. NEVER ASSUME! var db = require(‘database’); db.open(function (err) { db.write(‘mr-big’, bigData, function (err, data) { // ... unrelated logic db.close(); }); db.read(‘foo2’, function (err, data) { // ... some work done }); }); Accidents happen... Wednesday, May 29, 13
  • 9. NEVER ASSUME! var db = require(‘database’); db.open(function (err) { db.write(‘mr-big’, bigData, function (err, data) { // ... unrelated logic db.close(); }); db.read(‘foo2’, function (err, data) { // ... some work done }); }); close() might affect read() Wednesday, May 29, 13
  • 10. A MORE COMPLEX EXAMPLE... Wednesday, May 29, 13
  • 13. DEPENDENCY AWARENESS What can fail, WILL FAIL! Never assume a dependency is reliable! Contingency plans - failover, redundancy, fail-fast, etc Pro-active monitoring Load test, stress test, chaos monkey, etc Remember, what can fail, WILL FAIL! Wednesday, May 29, 13
  • 15. JAVASCRIPT MASTERY Code Execution Order Sanitization & Validation Scope Control Flow Wednesday, May 29, 13
  • 17. EXECUTION ORDER var mq = require(‘mq’); mq.conn(...); mq.on(‘ready’, function () { mq.send(‘batman’); mq.on(‘message’, function (msg) { console.log(msg); mq.close(); }); }); mq is never closed! send() executes before on() Wednesday, May 29, 13
  • 18. DOIN’ IT RIGHT! var mq = require(‘mq’); mq.conn(...); mq.on(‘ready’, function () { mq.on(‘message’, function (msg) { console.log(msg); mq.close(); }); mq.send(‘batman’); }); Swap places Wednesday, May 29, 13
  • 19. SANITIZATION & VALIDATION function foodForKittens(num) { return num * 10; } foodForKittens(); num is not validated, is undefined this will fail! Wednesday, May 29, 13
  • 21. SANITIZATION & VALIDATION var db = require(‘database’); var conn = db.open(...); function writeToDb(conn, cb) { conn.write(bigData, function (err, res) { if (err) { cb(err); return; } cb(null, res); }); }); writeToDb(conn, ghostCallback); Wednesday, May 29, 13
  • 23. var db = require(‘database’); var conn = db.open(...); function writeToDb(conn, cb) { conn.write(bigData, function (err, res) { if (err) { cb(err); return; } cb(null, res); }); }); writeToDb(conn, ghostCallback); what if open() returned undefined? this will throw an exception! Wednesday, May 29, 13
  • 24. var db = require(‘database’); var conn = db.open(...); function writeToDb(conn, cb) { conn.write(bigData, function (err, res) { if (err) { cb(err); return; } cb(null, res); }); }); writeToDb(conn, ghostCallback); What if ghostCallback is undefined? These will fail too! Wednesday, May 29, 13
  • 25. DOIN’ IT RIGHT! var db = require(‘database’); var conn = db.open(...); function writeToDb(conn, cb) { if (typeof conn !== ‘object’) { // ... handle error ... } if (typeof cb !== ‘function’) { // ... handle error ... } conn.write(bigData, function (err, res) { if (err) { cb(err); return; } cb(null, res); }); }); writeToDb(conn, ghostCallback); Validate your input, especially when they involve functions or methods that you need to invoke in your code. These are not the time to fail-fast! Wednesday, May 29, 13
  • 26. DON’T GO OVERBOARD... Validate only necessary parameters Method invocations (anObject.method()) Function invocations (aFunction()) Have a proper error/exception handling policy Validate for correctness, not existence Correctness: typeof a === ‘object’ Existence: a !== undefined Wednesday, May 29, 13
  • 27. SCOPE AWARENESS Plagues most callback-based code Bad practice leads to costly debugging waste New JS programmers not aware of scoping JS scoping is a simple but weird thing (to non-JS programmers) Wednesday, May 29, 13
  • 28. SCOPE!!! var a = ‘outside’; if (true) { var a = ‘inside’; console.log(a); } console.log(a); What is the output? > node test.js inside inside Wednesday, May 29, 13
  • 29. SCOPE!!! Non-JS programmers: a inside the if block is “inside” a outside the if block is “outside” JS programmers: they are both “inside” JS scope by function Wednesday, May 29, 13
  • 30. SCOPE CHAINS!!! var avar = 1; (function outer1() { var avar = 2; (function inner1() { var avar = 3; console.log(avar); // outputs 3 })(); (function inner2() { console.log(avar); // outputs 2 })(); })(); (function outer2() { (function inner3() { console.log(avar); // outputs 1 })(); })(); inner1() local - found! inner2() local - nope outer1() - found! inner3() local - nope outer2() - nope global - found! Wednesday, May 29, 13
  • 31. HOISTING VARIABLES function () { for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { // ... do something } } } function () { var i, j; // now the scope is clear for i & j for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { // ... do something } } } Below is far clearer what individual variable scopes are: Wednesday, May 29, 13
  • 32. CONTROL FLOW Node.js’ async nature makes it unintuitive to predict control flow I <3 async (github.com/caolan/async) Control flow is ugly. Welcome to Javascript. Async will save your life. Use it. Wednesday, May 29, 13
  • 33. CONTROL FLOW var fs; fs = require(‘fs’); fs.readFile(‘./myfile.txt’, function (err, data) { if (err) { console.log(err); return; } fs.writeFile(‘./myfile2.txt’, data, function (err) { if (err) { console.log(err); return; } // ... do stuff ... }); }) Wednesday, May 29, 13
  • 34. CONTROL FLOW Callback hell! Step 1 Step 2 Step 3 Step 4 Step 5 Wednesday, May 29, 13
  • 35. mod.step1(function () { mod.step2(function () { mod.step3(function () { mod.step4(function () { mod.step5(function () { // ... too many levels ... }); }); } }); }); Wednesday, May 29, 13
  • 36. CONTROL FLOW var async, fs; async = require(‘async’); fs = require(‘fs’); async.waterfall([ function step1(callback) { fs.readFile(‘./myfile.txt’, callback); }, function step2(data, callback) { fs.writeFile(‘./myfile2.txt’, data, callback); } ], function (err) { // ... execute something in the end ... }); Wednesday, May 29, 13
  • 38. GOLDEN RULES Golden Rules of Defensive Programming Proper error handling policy Intelligent logging Design for failure Wednesday, May 29, 13
  • 39. ERROR HANDLING Never, ever HIDE errors > node app.js 2>&1 /dev/null ob.callback(function (err, data) { if (err) {} console.log(data); }); socket.on(‘error’, function () {}); Wednesday, May 29, 13
  • 40. ERROR HANDLING I WILL FIND YOU AND I WILL CRASH YOU Wednesday, May 29, 13
  • 41. ERROR HANDLING Standardize error handling in the app Log to error DB Output to error file Output error to a stream Use a logging library Ask a leprechaun to manage it etc Wednesday, May 29, 13
  • 42. LOGGING How do you feel if your “log” looks like this? > tail -f error.log [12:01:55] ERROR - General error detected [12:01:56] ERROR - General error detected [12:01:57] ERROR - General error detected [12:01:58] ERROR - General error detected [12:01:59] ERROR - General error detected [12:02:00] ERROR - General error detected [12:02:01] ERROR - General error detected Wednesday, May 29, 13
  • 44. LOGGING Logs are the first place you go to find out what happened Standardize a log location for each app Make logs easy to access for developers Wednesday, May 29, 13
  • 45. DESIGN FOR FAILURE Common steps to designing software: 1 - what should it do? 2 - how do I do it? 3 - how do I deploy? 4 - done Wednesday, May 29, 13
  • 46. DESIGN FOR FAILURE Proper steps in defensive programming: 1 - what should it do? 2 - how many ways can it fail? 3 - how do I know when it fails? 4 - how do I prevent it from failing? 5 - write code accordingly Wednesday, May 29, 13
  • 47. DESIGN FOR FAILURE Nothing is reliable TCP can fail Network can go down Servers can run out of memory Cows might fly through the sky crashing into your datacenter and flooding the server rooms with milk and destroying everything Wednesday, May 29, 13
  • 48. DESIGN FOR FAILURE Designing for failure mindset & methodologies: Identify SPOF (single point of failures) Redundancy, failover, monitoring Fail-fast, start-fast Persist important data Reliability & Consistency > Speed Code is liability Wednesday, May 29, 13
  • 49. ~ The End ~ Wednesday, May 29, 13