Skip to content

Instantly share code, notes, and snippets.

@IronSavior
Last active August 7, 2017 23:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IronSavior/d83815668b1ea0b5cc56569896c0c88c to your computer and use it in GitHub Desktop.
Save IronSavior/d83815668b1ea0b5cc56569896c0c88c to your computer and use it in GitHub Desktop.
Composed error handling policy -- mix sync/async without missing errors
const error_policy = require('./error-policy');
// EventEmitter example
const {Readable} = require('stream');
class MyReadable extends Readable {
constructor(){
super(...arguments);
this.policy = error_policy(e => this.emit('error', e));
}
_read(){
// No async calls, but error policy expressed more simply than with explicit try/catch structures
this.policy.enforce(_ => this.push(some_sync_call()));
}
}
// Transform stream with mix of sync/async
const {Transform} = require('stream');
class MyTransform extends Transform {
_transform( chunk, enc, done ){
let policy = error_policy(done);
policy.enforce(_ => {
sync_thing();
async_thing(policy.fn(result => {
// By wrapping in policy.fn() we can be CERTAIN that errors thrown in async code are handled
other_sync_thing(); // Any throws here will pass error to done()
done(); // call to done with no arg signals success
}));
});
}
}
// Promise example -- promises capture throws fairly well until you introduce an async call
function promise_example(){
return Promise.new((resolve, reject) => {
async_thing(error_policy(reject).fn(result =>
resolve(sync_thing(result))
));
});
}
// Async calllback example
function async_callback_example(){
let policy = error_policy(console.trace);
setImmediate(policy.fn(sync_thing));
}
// Predicate example
function predicate_example(){
// pretend "this" is an object managing an array of resources and has an error policy property.
// We want to call sync_operation on each resource regardless of errors, but we also want to handle those errors.
this.resources.forEach(this.policy.fn(item => item.sync_operation()));
}
"use strict";
// Composed error handling policy -- Sugar to make it easier to properly handle errors in mixed sync/async code
module.exports = function make_error_policy( error_handler ){
let enforce = (f, ...args) => {
try{
return f(...args);
} catch(e){
error_handler(e);
}
};
let fn = (f, ...bound_args) => (...args) => enforce(f, ...bound_args, ...args);
return {enforce, fn};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment