npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

failboat

v3.0.0

Published

Generic error routing

Downloads

6,155

Readme

Failboat

Your Shipment of Fail has Arrived

Failboat is the boat that transports your failures to the right destination.

The idea is that you tag your errors with information abort the error and the context they appeared in. This information is used to route the error to the correct error handler.

The only requirement for routing errors to their handlers is that the error contains a property tags that is a non-empty array of strings.

Installation

Node

Install it with NPM or add it to your package.json:

$ npm install failboat

Then:

var Failboat = require('failboat');

Browser

Include Failboat.js.

<script src="Failboat.js"></script>

this will expose the Failboat constructor under the following namespace:

var Failboat = com.one.Failboat;

RequireJS

Include the library with RequireJS the following way:

require.config({
    paths: {
        failboat: 'path/to/failboat/lib/Failboat.js'
    }
});

define(['failboat'], function (Failboat) {
   // Your code
});

Example

The routing is best explained by example.

var context = {
    showError: function (message) {
        console.log(message);
    }
};

var failboat = new Failboat({
    '404 FolderNotFound': function () {
        this.showError('Folder not found');
    },
    '404': function () {
        this.showError('Generic not found handler');
    },
    '409': function () {
        this.showError('Generic conflict handler');
    },
    '502, 503': function () {
        this.showError('Could not connect to the server');
    },
    '12029': '503'
}, context);

failboat = failboat.extend({
    '401': function () {
        this.showError('Unauthorized operation');
    }
});

failboat = failboat.extend({
    '404 FolderNotFound LoadMailsAction': function (err) {
        this.showError('Folder not found while loading mails');
    }
});

The above code defines a failboat with three levels. The first configuration is the base level. When a failboat is extended a new failboat is created with the given configuration. The child failboat will have a reference to the parent failboat.

Each error handler function is executed in the context given to the base failboat. When extending a failboat the execution context is inherited from the parent.

When you call handleError on a failboat it will try to route the error at the top level, if it does not find an appropiate handler it will call handleError on the parent failboat.

Routing an error will find the route where the words matches the longest prefix of the tags array.

Given the example code above the following errors will result in the output shown below:

var err = Failboat.tag(new Error(), '404', 'FolderNotFound', 'LoadMailsAction');
failboat.handleError(err);

will print Folder not found while loading mails to the console.

var err = Failboat.tag(new Error(), '404', 'FolderNotFound');
failboat.handleError(err);

will print Folder not found to the console.

var err = Failboat.tag(new Error(), '404');
failboat.handleError(err);

will print Generic not found handler to the console.

var err = Failboat.tag(new Error(), '404', 'MailNotFound', 'GetMailPartAction');
failboat.handleError(err);

will print Generic not found handler to the console.

var err = Failboat.tag(new Error(), '401', 'LoadMailsAction');
failboat.handleError(err);

will print Unauthorized operation to the console.

var err = Failboat.tag(new Error(), '404', 'FolderNotFound');
failboat.handleError(err);

will print Folder not found to the console.

var err = Failboat.tag(new Error(), '502');
failboat.handleError(err);

will print Could not connect to the server to the console.

var err = Failboat.tag(new Error(), '503');
failboat.handleError(err);

will print Could not connect to the server to the console.

var err = Failboat.tag(new Error(), '12029');
failboat.handleError(err);

will print Could not connect to the server to the console.

API

new Failboat()

Creates a new failboat without routes.

var failboat = new Failboat();

new Failboat(routes)

Creates a new failboat with the given routes.

var failboat = new Failboat({
    '404': function () {
        console.log('Generic not found handler');
    },
    '404 FolderNotFound': function () {
        console.log('Folder not found');
    },
    '409': function () {
        console.log('Generic conflict handler');
    }
});

If you make a route called * all error that can't be routed to a more specific will fallback use this route.

new Failboat(routes, context)

Creates a new failboat with the given routes. Each error handler will be executed in the given context. If the failboat is extended the context will be inherited.

var context = {
    showError: function (message) {
        console.log(message);
    }
};

var failboat = new Failboat({
    '404': function () {
        this.showError('Generic not found handler');
    },
    '404 FolderNotFound': function () {
        this.showError('Folder not found');
    },
    '409': function () {
        this.showError('Generic conflict handler');
    }
}, context);

Failboat.tag(err, tags...)

Add the given tags to the err. If the error has already been tagged the tags will be added to the list of tags.

Failboat.tag(err, 'this', 'is');
Failboat.tag(err, 'some', 'tags');

Now err.tags contains the tags ['this', 'is', 'some', 'tags'].

failboat.extend(routes)

Creates a new failboat with the given routes and a pointer to the failboat that is extended.

failboat = failboat.extend({
    '401': function () {
        console.log('Unauthorized operation');
    }
});

failboat.handleError(err)

Routes the given error to a handler based on the configured routes and the tags on the error.

Routing an error will find the route where the words matches the longest prefix of the tags array. If it does not find an appropiate handler it will delegate to it's parent failboat for handling the error.

Returns true if the error was handled by this failboat or one of it's ancestors; otherwise false is returned.

var err = Failboat.tag(new Error(), '404', 'FolderNotFound', 'LoadMailsAction');
failboat.handleError(err);

failboat.handleError(err, routes)

Syntaxtic sugar for:

failboat.extend(routes).handleError(err);

Event: failboat.onErrorRouted = handler

When an error has been routed an onErrorRouted will be called with the error and the matching route. That gives you the posibility to do logging and crash reporting in a central place.

The onErrorRouted will be called for each failboat where a handler has been attached. Usually the onErrorRouted handler should be attached to the base failboat.

failboat.onErrorRouted = function (err, matchingRoute) {
    if (matchingRoute) {
        console.log('Error: "' + err.message + '" handled by ' + matchingRoute);
        if (500 <= err.status && err.status < 600) {
            // Report server crash
        }
    } else {
        console.log('Missing handler for: "' + err.message + '"');
    }
};

License

Copyright © 2014, One.com

Failboat is licensed under the BSD 3-clause license, as given at http://opensource.org/licenses/BSD-3-Clause