Skip to content

Instantly share code, notes, and snippets.

@andrewplummer
Created January 12, 2017 12:37
Show Gist options
  • Save andrewplummer/845c460a725d74f8ccf452480ad6d103 to your computer and use it in GitHub Desktop.
Save andrewplummer/845c460a725d74f8ccf452480ad6d103 to your computer and use it in GitHub Desktop.
Python/Ruby style error handling
(function() {
// lib
// Private
function canHandleError(err, block) {
return !block.errorClasses || block.errorClasses.some(function(errorClass) {
return err instanceof errorClass;
});
}
function begin(fn) {
let rescueBlocks = [], ensureBlock;
for (let i = 1, block; block = arguments[i]; i++) {
if (block.type === 'rescue') {
rescueBlocks.push(block);
} else if (block.type === 'ensure') {
ensureBlock = block.handler;
}
}
try {
fn();
} catch(err) {
for (let i = 0, block; block = rescueBlocks[i]; i++) {
if (canHandleError(err, block)) {
block.handler(err);
break;
}
}
} finally {
if (ensureBlock) {
ensureBlock();
}
}
}
function rescue(...args) {
if (args.length === 1) {
return {
type: 'rescue',
handler: args[0]
}
}
let errorClasses = args[0];
let handler = args[1];
if (!Array.isArray(errorClasses)) {
errorClasses = [errorClasses];
}
return {
type: 'rescue',
handler: handler,
errorClasses: errorClasses
}
}
function ensure(fn) {
return {
type: 'ensure',
handler: fn
}
}
})();
// Errors
class CustomError extends Error {
constructor(code, message) {
super(message);
this.code = code;
}
}
class FireError extends CustomError {}
class WaterError extends CustomError {}
begin(function() {
let x = arguments.slice(1);
console.info(x);
//throw new WaterError('No water available');
},
rescue(WaterError, function(err) {
console.info('No water available');
}),
rescue(ReferenceError, function(err) {
console.info('Bad reference!');
}),
rescue(TypeError, function(err) {
console.info('bad type');
}),
rescue(function(err) {
console.info('Not sure what', err);
}),
ensure(function() {
console.info('Making sure!');
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment