SlideShare una empresa de Scribd logo
1 de 130
Descargar para leer sin conexión
To Err Is Human
Alex Liu
@stinkydofu
aliu@netflix.com
☐ avoidance
☐ acceptance
☐ avoidance
☐ acceptance☑
The Road To Happiness
‣ Handling Errors and Exceptions
‣ Preserving History
‣ The Problem With Catch
Handling Errors and
Exceptions
1
Error
> new Error();
kinds of errors
two
Expected
Expected
Expected
‣ invalid user input
‣ bad JSON input
‣ file not found
‣ request timeout
‣ request 500
Unexpected
Unexpected
Unexpected
‣ programmer typos
‣ read property of
undefined
‣ undefined is not a
function
How do I
communicate
expected errors?
Exception
> throw new Error();
an exception is a
thrown error
You could throw anything
> throw { foo: bar };
> throw 0;
> throw 'my error';
> throw 0;
undefined
> throw 'something happened';
something happened
> throw new Error('something happened');
Error: something happened
at repl:1:7
at REPLServer.defaultEval (repl.js:132:27)
at bound (domain.js:254:14)
at REPLServer.runBound [as eval] (domain.js:267:12)
at REPLServer.<anonymous> (repl.js:279:12)
at REPLServer.emit (events.js:107:17)
at REPLServer.Interface._onLine (readline.js:214:10)
at REPLServer.Interface._line (readline.js:553:8)
at REPLServer.Interface._ttyWrite (readline.js:830:14)
index.js
index.js data.js get.js
index.js data.js get.js
throw!
index.js data.js get.js
throw!
catch?
index.js data.js get.js
throw!catch?
index.js data.js get.js
throw!catch?
catch (e) {
// run!
}
index.js data.js get.js
throw!
CRASH! throw!
index.js data.js get.js
throw / try / catch
try {
var price = getStockPrice('NFLX');
document.write('NFLX: ' + price);
} catch(err) {
// err instanceof Error => true
document.write('NFLX: unavailable');
}
Can we catch?
try {
getStockPrice('NFLX', function(err) {
if (err) { throw (err); }
/* continue as normal */

});
} catch(err) {
/* error handling */
}
Error first callbacks (errbacks)
getStockPrice('NFLX', function(err, price) {
if (err) { /* handle err! */ }
document.write('NFLX: ' + price);
});
Error first callbacks (errbacks)
getStockPrice('NFLX', function(err, price) {
if (err) { /* handle err! */ }
document.write('NFLX: ' + price);
});
Error first callbacks (errbacks)
getStockPrice('NFLX', function(err, price) {
if (err) {
document.write('NFLX: unavailable');
return;
}
document.write('NFLX: ' + price);
});
Bubble up if you can’t handle it
function drawStockPrice(callback) {
getStockPrice('NFLX', function(err, price) {
return callback(err);
});
}
index.js
index.js data.js get.js
cb(err)
index.js data.js get.js
cb(err) cb(err)
if (err) {
...
}
index.js data.js get.js
cb(err) cb(err)
SWALLOWED! cb(err)cb(err)
index.js data.js get.js
errbacks are a
channel
for expected errors
> throw err;
> callback(err);
sync
async
nope
nope
nope
nope
nope
nope
nopenope
nope
nopenope
nope
nope
nope
nope
nope
nope
throw / try / catch

when in async env
sanely
you can’t
favor
errbacks
because of
consistency
How do I
communicate
unexpected errors?
unexpected errors are
thrown
automatically
process.on('uncaughtException', function(err) {
...
});
Catch ‘em all, even async
process.on('uncaughtException', function(err) {
...
});
Catch ‘em all, even async
window.onerror = function(err) {
...
});
process.on('uncaughtException', function(err) {
...
});
Catch ‘em all, even async
window.onerror = function(err) {
...
});
_BAD IDEA_
Can you recover?
function dispatch(doThings) {
if (!Array.isArray(doThings)) {
throw new TypeError('not an array');
}
for (var i = 0; i < doThings.length; i++) {
if (typeof doThings[i] !== 'function') {
throw new TypeError('not a function');
}
}
for (var i = 0; i < doThings.length; i++) {
doThings[i]();
}
}
Can you recover?
function dispatch(doThings) {
if (!Array.isArray(doThings)) {
throw new TypeError('not an array');
}
for (var i = 0; i < doThings.length; i++) {
if (typeof doThings[i] !== 'function') {
throw new TypeError('not a function');
}
}
for (var i = 0; i < doThings.length; i++) {
doThings[i]();
}
}
<----------------------------------- (1)
Can you recover?
function dispatch(doThings) {
if (!Array.isArray(doThings)) {
throw new TypeError('not an array');
}
for (var i = 0; i < doThings.length; i++) {
if (typeof doThings[i] !== 'function') {
throw new TypeError('not a function');
}
}
for (var i = 0; i < doThings.length; i++) {
doThings[i]();
}
}
<----------------------------------- (1)
<------------------------------- (2)
Can you recover?
function dispatch(doThings) {
if (!Array.isArray(doThings)) {
throw new TypeError('not an array');
}
for (var i = 0; i < doThings.length; i++) {
if (typeof doThings[i] !== 'function') {
throw new TypeError('not a function');
}
}
for (var i = 0; i < doThings.length; i++) {
doThings[i]();
}
}
<----------------------------------- (1)
<------------------------------- (2)
<-------------------------------------------------------- (3)
Catch and do what…?
for (var i = 0; i < doThings.length; i++) {
try {
doThings[i]();
} catch (e) {
...
}
}
Catch and do what…?
for (var i = 0; i < doThings.length; i++) {
try {
doThings[i]();
} catch (e) {
...
}
}
<--------------------- what goes here?
programmer err : rollback
::
programmer err : rollback
::
rollback err : ?
you can’t fix unexpected
errors because their
existence is
unexpected
in node.js,
abort

on unexpected errors
goal is to


the blast radius
(not to write bug free code)
minimize
continuing after an
unhandled exception is a
trade off
_BROKEN_
program error : program crash
::
program error : program crash
::
OS error : ?
program error : program crash
::
OS error : OS crash
in the browser,
report

all unexpected errors
avoid

handling errors in global
exception handlers
Preserving History 2
Working backward…
function getEpicStory(cb) {
database.get('iliad', function(err, data) {
if (err) {
return cb(err);
}
return cb(null, data);
});
}
We can do better
database.get('iliad', function(err, data) {
if (err) {
err.cause = 'db error!';
err.timestamp = new Date();
return cb(err);
}
return cb(null, data);
});
VError: we can do even better
database.get('iliad', function(err, data) {
if (err) {
return cb(new VError(err, 'db error!'));
}
return cb(null, data);
});
VError: we can do even better
// redis error
[Error: missing key]
// our verror
{ [VError: db error: missing key]
jse_shortmsg: 'db error',
jse_summary: 'db error: missing key',
jse_cause: [Error: missing key],
message: 'db error: missing key' }
[2015-10-02T06:41:54.389Z] ERROR: test/11497 on lgml-aliu: db error: missing key
VError: db error: missing key
at Object.<anonymous> (/Users/aliu/Desktop/test/a.js:6:12)
at Module._compile (module.js:434:26)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:117:18)
at node.js:951:3
Caused by: Error: missing key
at Object.<anonymous> (/Users/aliu/Desktop/test/a.js:5:12)
at Module._compile (module.js:434:26)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:117:18)
at node.js:951:3
restify-errors: the bees’ knees
var errs = require('restify-errors');
errs.makeConstructor('DatabaseError', {
fooProp: 'someVal'
});
var myErr = new errs.DatabaseError('db error!');
// myErr.fooProp => someVal
restify-errors: the bees’ knees
var myErr = new errs.DatabaseError('db error!');
myErr instanceof errs.DatabaseError // => true
myErr instanceof VError // => true
myErr instanceof Error // => true
Serving out the UI
request('/api/story', function(err, fpStoryData) {
if (err instanceof HttpError) {
return res.render('NetworkErrorPage');
} else if (err instanceof DatabaseError) {
return res.render('UnavailablePage');
} else {
return res.render('ErrorPage');
}
res.render('iliad', fpStoryData);
});
[2015-10-06T17:50:31.561Z] ERROR: test/64987 on lgml-aliu: rendering error!
RenderError: rendering error page!
at Object.<anonymous> (/Users/aliu/Desktop/test/test4.js:10:10)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
Caused by: DataValidationError: data validation error
at Object.<anonymous> (/Users/aliu/Desktop/test/test4.js:10:32)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
Caused by: RequestError: request error
at Object.<anonymous> (/Users/aliu/Desktop/test/test4.js:10:63)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
Caused by: BadRequestError: http 400
at Object.<anonymous> (/Users/aliu/Desktop/test/test4.js:10:86)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
[2015-10-06] ERROR: test/64987 on lgml-aliu: rendering error!

Error: something happened
at repl:1:7
at REPLServer.defaultEval (repl.js:132:27)
at bound (domain.js:254:14)
at REPLServer.runBound [as eval] (domain.js:267:12)
at REPLServer.<anonymous> (repl.js:279:12)
at REPLServer.emit (events.js:107:17)
at REPLServer.Interface._onLine (readline.js:214:10)
at REPLServer.Interface._line (readline.js:553:8)
at REPLServer.Interface._ttyWrite (readline.js:830:14)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
use


for expected errors
typed errors
3
The problem with catch
But
{abstraction}
solved this
already!?
try: catch ‘em all
try {
if (Math.random() > 0.5) {
JSON.parse(input);
} else {
var x = y + 1;
}
} catch (err) {...}
> [SyntaxError: Unexpected token b]
> [ReferenceError: y is not defined]
expected:
unexpected:
JSON.parse(input);
var x = y + 1;
Catching typed errors
catch (err) {
if (err instanceof SyntaxError) {
...
}
}
Don’t forget to rethrow!
catch (err) {
if (err instanceof SyntaxError) {
...
} else {
throw err;
}
}
Centralize throwing
catch (err) {
throwUnexpected(err);
// handle err if not thrown
}
expected vs unexpected…?
catch (err) {
if (err instanceof SyntaxError) {
...
} else {
throw err;
}
}
expected vs unexpected…?
> JSON.parse('bad input');
> vart x;
try/catch cannot
differentiate
source of errors
try: reduce surface area
try {
JSON.parse(input);
} catch (err) {
...
}
var x = y + 1; <------------------- throws
be very
targeted
with try / catch
promises: catch ‘em all


foo.then(foo2)
.then(foo3)
.catch(function(err) {
...
});

promises: unexpected behavior

























foo.then(foo2)
.then(fooError)
.catch(function(err) {
if (!(err instanceof ExpectedErr)) {
throw err;
}
});
$ node promiseDemo.js
Unhandled rejection ReferenceError: y is not defined
at foo (/test/promiseDemo.js:14:13)
at /test/promiseDemo.js:8:3
at processImmediate [as _immediateCallback] (timers.js:368:17)
From previous event:
at Object.<anonymous> (/test/promiseDemo.js:7:3)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Function.Module.runMain (module.js:467:10)
at startup (node.js:134:18)
at node.js:961:3
$
$ echo $?
$ echo $?
0
promises: unexpected behavior

























foo.then(foo2)
.then(fooError)
.catch(function(err) {
if (!(err instanceof ExpectedErr)) {
throw err;
}
});
promises: call done()
foo.then(foo2)
.then(fooError)
.catch(function(err) {
if (!(err instanceof ExpectedErr)) {
throw err;
}
})
.done();
bluebird: catch only expected












foo.then(foo2)
.then(fooError)
.catch(ExpectedError, function(err) {
...
});
// EVERYTHING else throws, exits 1!
bluebird: throw by default
Promise.onPossiblyUnhandledRejection(function(e) {
throw e;
});
surfacing unexpected
errors should NOT be
opt-in
Making Catch Better
You don't need to sell me
-- we had } catch (e if ...) {
in SpiderMonkey and
proposed it for ES3 (in
1998).
- Brendan Eich
try {
...
} catch (e if ...) {
...
}
Refutable Pattern Matching
GuardedPattern(refutable) ::= Pattern(refutable) "if"
AssignmentExpression
Looking Forward
for rich error objects
5
npm install verror
npm install restify-errors
Handle every error from
every async API
4
Understand how your
abstractions handle errors
3
(swallow? rethrow?)
Abort immediately on
unexpected errors to
minimize the blast radius
2
Design and build applications
with error handling in mind
1
(exceptions are NOT exceptional!)
Error handling bible
‣ https://www.joyent.com/developers/node/
design/errors
Aborting on unexpected errors
‣ https://github.com/nodejs/node-v0.x-archive/
issues/5114
‣ https://github.com/nodejs/node-v0.x-archive/
issues/5149
Module up!
‣ verror
‣ https://github.com/davepacheco/node-verror
‣ restify-errors
‣ https://github.com/restify/errors
Get involved!
‣ https://esdiscuss.org/topic/try-catch-conditional-
exceptions-in-light-of-generators
‣ http://wiki.ecmascript.org/doku.php?
id=strawman:pattern_matching
Fin
Alex Liu
@stinkydofu
aliu@netflix.com
Image Credits
Image Credits
Image Credits
Image Credits
‣ http://lizclimo.tumblr.com/post/77531229510/youre-doing-it-wrong
‣ http://fantasio.deviantart.com/art/Godzilla-in-the-mountains-454304871
‣ http://rockpapercynic.tumblr.com/post/85581052929/first-revealed-pagew-your-bad-
idea-illustration

Más contenido relacionado

La actualidad más candente

Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Wilson Su
 
Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Wilson Su
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mockskenbot
 
10 Catalyst Tips
10 Catalyst Tips10 Catalyst Tips
10 Catalyst TipsJay Shirley
 
ES6, 잘 쓰고 계시죠?
ES6, 잘 쓰고 계시죠?ES6, 잘 쓰고 계시죠?
ES6, 잘 쓰고 계시죠?장현 한
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS ProgrammersDavid Rodenas
 
Всеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsВсеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsYandex
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptŁukasz Kużyński
 
JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)Anders Jönsson
 
Unbreakable: The Craft of Code
Unbreakable: The Craft of CodeUnbreakable: The Craft of Code
Unbreakable: The Craft of CodeJoe Morgan
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaExoLeaders.com
 
Обзор фреймворка Twisted
Обзор фреймворка TwistedОбзор фреймворка Twisted
Обзор фреймворка TwistedMaxim Kulsha
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516SOAT
 
"Auth for React.js APP", Nikita Galkin
"Auth for React.js APP", Nikita Galkin"Auth for React.js APP", Nikita Galkin
"Auth for React.js APP", Nikita GalkinFwdays
 
Unit testing with mocha
Unit testing with mochaUnit testing with mocha
Unit testing with mochaRevath S Kumar
 

La actualidad más candente (19)

Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8
 
Introduccion a Jasmin
Introduccion a JasminIntroduccion a Jasmin
Introduccion a Jasmin
 
Why Sifu
Why SifuWhy Sifu
Why Sifu
 
Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mocks
 
10 Catalyst Tips
10 Catalyst Tips10 Catalyst Tips
10 Catalyst Tips
 
Say It With Javascript
Say It With JavascriptSay It With Javascript
Say It With Javascript
 
ES6, 잘 쓰고 계시죠?
ES6, 잘 쓰고 계시죠?ES6, 잘 쓰고 계시죠?
ES6, 잘 쓰고 계시죠?
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Всеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsВсеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.js
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascript
 
JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)
 
Unbreakable: The Craft of Code
Unbreakable: The Craft of CodeUnbreakable: The Craft of Code
Unbreakable: The Craft of Code
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
 
Обзор фреймворка Twisted
Обзор фреймворка TwistedОбзор фреймворка Twisted
Обзор фреймворка Twisted
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516
 
Easy Button
Easy ButtonEasy Button
Easy Button
 
"Auth for React.js APP", Nikita Galkin
"Auth for React.js APP", Nikita Galkin"Auth for React.js APP", Nikita Galkin
"Auth for React.js APP", Nikita Galkin
 
Unit testing with mocha
Unit testing with mochaUnit testing with mocha
Unit testing with mocha
 

Destacado

Node Interactive Debugging Node.js In Production
Node Interactive Debugging Node.js In ProductionNode Interactive Debugging Node.js In Production
Node Interactive Debugging Node.js In ProductionYunong Xiao
 
[JSDC 2016] Codex: Conditional Modules Strike Back
[JSDC 2016] Codex: Conditional Modules Strike Back[JSDC 2016] Codex: Conditional Modules Strike Back
[JSDC 2016] Codex: Conditional Modules Strike BackAlex Liu
 
Slaying Monoliths with Node and Docker
Slaying Monoliths with Node and DockerSlaying Monoliths with Node and Docker
Slaying Monoliths with Node and DockerYunong Xiao
 
Netflix JavaScript Talks - Scaling A/B Testing on Netflix.com with Node.js
Netflix JavaScript Talks - Scaling A/B Testing on Netflix.com with Node.jsNetflix JavaScript Talks - Scaling A/B Testing on Netflix.com with Node.js
Netflix JavaScript Talks - Scaling A/B Testing on Netflix.com with Node.jsChris Saint-Amant
 
Observable Node.js Applications - EnterpriseJS
Observable Node.js Applications - EnterpriseJSObservable Node.js Applications - EnterpriseJS
Observable Node.js Applications - EnterpriseJSYunong Xiao
 
Debugging node in prod
Debugging node in prodDebugging node in prod
Debugging node in prodYunong Xiao
 

Destacado (6)

Node Interactive Debugging Node.js In Production
Node Interactive Debugging Node.js In ProductionNode Interactive Debugging Node.js In Production
Node Interactive Debugging Node.js In Production
 
[JSDC 2016] Codex: Conditional Modules Strike Back
[JSDC 2016] Codex: Conditional Modules Strike Back[JSDC 2016] Codex: Conditional Modules Strike Back
[JSDC 2016] Codex: Conditional Modules Strike Back
 
Slaying Monoliths with Node and Docker
Slaying Monoliths with Node and DockerSlaying Monoliths with Node and Docker
Slaying Monoliths with Node and Docker
 
Netflix JavaScript Talks - Scaling A/B Testing on Netflix.com with Node.js
Netflix JavaScript Talks - Scaling A/B Testing on Netflix.com with Node.jsNetflix JavaScript Talks - Scaling A/B Testing on Netflix.com with Node.js
Netflix JavaScript Talks - Scaling A/B Testing on Netflix.com with Node.js
 
Observable Node.js Applications - EnterpriseJS
Observable Node.js Applications - EnterpriseJSObservable Node.js Applications - EnterpriseJS
Observable Node.js Applications - EnterpriseJS
 
Debugging node in prod
Debugging node in prodDebugging node in prod
Debugging node in prod
 

Similar a To Err Is Human

Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the mastersAra Pehlivanian
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testingVisual Engineering
 
Promise: async programming hero
Promise: async programming heroPromise: async programming hero
Promise: async programming heroThe Software House
 
Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterSimen Li
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsPiotr Pelczar
 
Deterministic simulation testing
Deterministic simulation testingDeterministic simulation testing
Deterministic simulation testingFoundationDB
 
2013-06-15 - Software Craftsmanship mit JavaScript
2013-06-15 - Software Craftsmanship mit JavaScript2013-06-15 - Software Craftsmanship mit JavaScript
2013-06-15 - Software Craftsmanship mit JavaScriptJohannes Hoppe
 
2013-06-24 - Software Craftsmanship with JavaScript
2013-06-24 - Software Craftsmanship with JavaScript2013-06-24 - Software Craftsmanship with JavaScript
2013-06-24 - Software Craftsmanship with JavaScriptJohannes Hoppe
 
Unit Testing Front End JavaScript
Unit Testing Front End JavaScriptUnit Testing Front End JavaScript
Unit Testing Front End JavaScriptFITC
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bitsChris Saylor
 
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListenerNode.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListenerIslam Sharabash
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptGuy Royse
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesAnkit Rastogi
 
What's New in JavaScript
What's New in JavaScriptWhat's New in JavaScript
What's New in JavaScriptDan Cohn
 
Javascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularJavascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularErik Guzman
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 

Similar a To Err Is Human (20)

Node.js - Best practices
Node.js  - Best practicesNode.js  - Best practices
Node.js - Best practices
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 
Promise: async programming hero
Promise: async programming heroPromise: async programming hero
Promise: async programming hero
 
Typescript barcelona
Typescript barcelonaTypescript barcelona
Typescript barcelona
 
Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitter
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
Deterministic simulation testing
Deterministic simulation testingDeterministic simulation testing
Deterministic simulation testing
 
Performance patterns
Performance patternsPerformance patterns
Performance patterns
 
2013-06-15 - Software Craftsmanship mit JavaScript
2013-06-15 - Software Craftsmanship mit JavaScript2013-06-15 - Software Craftsmanship mit JavaScript
2013-06-15 - Software Craftsmanship mit JavaScript
 
2013-06-24 - Software Craftsmanship with JavaScript
2013-06-24 - Software Craftsmanship with JavaScript2013-06-24 - Software Craftsmanship with JavaScript
2013-06-24 - Software Craftsmanship with JavaScript
 
Unit Testing Front End JavaScript
Unit Testing Front End JavaScriptUnit Testing Front End JavaScript
Unit Testing Front End JavaScript
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
 
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListenerNode.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
What's New in JavaScript
What's New in JavaScriptWhat's New in JavaScript
What's New in JavaScript
 
Know your errors
Know your errorsKnow your errors
Know your errors
 
Javascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularJavascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & Angular
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 

Último

%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...Nitya salvi
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is insideshinachiaurasa2
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfayushiqss
 
Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsBert Jan Schrijver
 

Último (20)

%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
 

To Err Is Human