SlideShare ist ein Scribd-Unternehmen logo
1 von 130
Downloaden Sie, um offline zu lesen
To Err Is Human
Alex Liu
@stinkydofu
aliu@netïŹ‚ix.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
‣ ïŹle 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 ïŹrst callbacks (errbacks)
getStockPrice('NFLX', function(err, price) {
if (err) { /* handle err! */ }
document.write('NFLX: ' + price);
});
Error ïŹrst callbacks (errbacks)
getStockPrice('NFLX', function(err, price) {
if (err) { /* handle err! */ }
document.write('NFLX: ' + price);
});
Error ïŹrst 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 ïŹx 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@netïŹ‚ix.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/ïŹrst-revealed-pagew-your-bad-
idea-illustration

Weitere Àhnliche Inhalte

Was ist angesagt?

ВсДĐČĐŸĐ»ĐŸĐŽ СтруĐșŃ‡ĐžĐœŃĐșĐžĐč: Node.js
ВсДĐČĐŸĐ»ĐŸĐŽ СтруĐșŃ‡ĐžĐœŃĐșĐžĐč: Node.jsВсДĐČĐŸĐ»ĐŸĐŽ СтруĐșŃ‡ĐžĐœŃĐșĐžĐč: Node.js
ВсДĐČĐŸĐ»ĐŸĐŽ СтруĐșŃ‡ĐžĐœŃĐșĐžĐč: Node.js
Yandex
 
ĐžĐ±Đ·ĐŸŃ€ фрДĐčĐŒĐČĐŸŃ€ĐșĐ° Twisted
ĐžĐ±Đ·ĐŸŃ€ фрДĐčĐŒĐČĐŸŃ€ĐșĐ° TwistedĐžĐ±Đ·ĐŸŃ€ фрДĐčĐŒĐČĐŸŃ€ĐșĐ° Twisted
ĐžĐ±Đ·ĐŸŃ€ фрДĐčĐŒĐČĐŸŃ€ĐșĐ° Twisted
Maxim Kulsha
 
Easy Button
Easy ButtonEasy Button
Easy Button
Adam Dale
 

Was ist angesagt? (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
 

Andere mochten auch

Andere mochten auch (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
 

Ähnlich wie To Err Is Human

Deterministic simulation testing
Deterministic simulation testingDeterministic simulation testing
Deterministic simulation testing
FoundationDB
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
Chris Saylor
 

Ähnlich wie 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...
 

KĂŒrzlich hochgeladen

Abortion Pill Prices Boksburg [(+27832195400*)] đŸ„ Women's Abortion Clinic in ...
Abortion Pill Prices Boksburg [(+27832195400*)] đŸ„ Women's Abortion Clinic in ...Abortion Pill Prices Boksburg [(+27832195400*)] đŸ„ Women's Abortion Clinic in ...
Abortion Pill Prices Boksburg [(+27832195400*)] đŸ„ Women's Abortion Clinic in ...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 

KĂŒrzlich hochgeladen (20)

WSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - Kanchana
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
 
%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
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Abortion Pill Prices Boksburg [(+27832195400*)] đŸ„ Women's Abortion Clinic in ...
Abortion Pill Prices Boksburg [(+27832195400*)] đŸ„ Women's Abortion Clinic in ...Abortion Pill Prices Boksburg [(+27832195400*)] đŸ„ Women's Abortion Clinic in ...
Abortion Pill Prices Boksburg [(+27832195400*)] đŸ„ Women's Abortion Clinic in ...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
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...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
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...
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 

To Err Is Human