SlideShare uma empresa Scribd logo
1 de 130
Baixar para ler offline
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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Destaque

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
 

Destaque (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
 

Semelhante 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
 

Semelhante 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

%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
%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
 
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
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
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
 
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
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Hararemasabamasaba
 
%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
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
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
 

Último (20)

%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
%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
 
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
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
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
 
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
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
%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
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
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...
 

To Err Is Human