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

terror

v1.4.0

Published

Base error class which will help you grep logs more effectively

Downloads

4,245

Readme

Terror NPM version Build Status

Development Dependency status

Base error class which will help you organize errors, generate informative logs and as result grep logs more effectively.

Trivial usage

var Terror = require('terror'),

    // declare error type with custom error codes and messages
    MyError = Terror.create('MyError', {
        STRANGE_THING_HAPPENS: 'Something strange happens'
    });

try {
    // ...

    if (typeof userInput === 'undefined') {
        // throw error
        throw new MyError(MyError.CODES.STRANGE_THING_HAPPENS);
        // or
        // throw MyError.createError(MyError.CODES.STRANGE_THING_HAPPENS);
    }
} catch (err) {
    // ensureError method returns err if it is an instance of MyError,
    // otherwise wrap Error instance in the MyError with default code UNKNOWN_ERROR
    MyError.ensureError(err)
        .log();
}

Constructor

new Terror(code, originalError);
new Terror(code, message);
new Terror(code);
new Terror();

Also can be called as a function, then calls self as the constructor internally and returns created instance.

Both arguments are not required:

  • if only code passed, message will got from Terror.MESSAGES hash by the code value as the key;
  • if code is absent, will be used default value Terror.CODES.UNKNOWN_ERROR.

Constructor methods

create(name, codes)

Returns constructor inherited from Terror. You must specify name for logging purpose.

Arguments:

  • {String} name – Error class name for logging;
  • {Object} [codes] - CODES hash { CODE_NAME: 'error message', … }

Example:

var AppError = Terror.create('AppError'),
    ControllerError = AppError.create('ControllerError', {
        IO_ERROR: 'Broken IO',
        FS_ERROR: 'Broken %fsName% file-system'
    });

extendCodes(codes)

Extends CODES and associated MESSAGES hashes using codes declaration. Method throws an error if codes uniqueness violated by extension.

Example:

var AppError = Terror
        .create('AppError')
        .extendCodes({
                BROKEN_CONFIG: 'Looks like configuration file is broken.',
                DB_CONNECTION_FAILED: 'Can not connect to database %db_host%'
        });

// now you can use AppError.CODES.BROKEN_CONFIG & AppError.CODES.DB_CONNECTION_FAILED to produce errors
new AppError(AppError.CODES.BROKEN_CONFIG);

setLogger(logger)

Set function which error class and its inheritors will use for logging. It called by log method with two arguments: message and level.

Example:

var log = [],
    logger = function(message, level) {
        log.push([ new Date(), level, message ].join());
    },
    MyError = Terror.create('MyError').setLogger(logger);

MyError.createError().log();

console.log(log.join('\n'));

createError(code, message | originalError | data)

Creates new Terror or its inheritor instance.

Arguments:

  • {Number} [code] – error code from CODES hash, Terror.CODES.UNKNOWN_ERROR used as default value;
  • {String|Error|Terror|Object} [message|originalError|data] ** if 2nd argument is String then use it as original error message; ** if 2nd argument is Error then use its message and call-stack to format original message; ** if 2nd argument is an Object then replace error message placeholders with provided data.

Example:

var MyError = Terror.create('MyError', {
        IO_ERROR: 'Broken IO',
        FS_ERROR: 'Broken %fsName% file-system'
    });

// valid createError calls

// "UNKNOWN_ERROR Terror: Unknown error"
Terror.createError();

// same as above
Terror.createError(Terror.CODES.UNKNOWN_ERROR);

// "UNKNOWN_ERROR MyError: Unknown error"
MyError.createError();

// "IO_ERROR MyError: Broken IO"
MyError.createError(MyError.CODES.IO_ERROR);

// "IO_ERROR MyError: Broken IO (Error: kbd int broken)"
MyError.createError(MyError.CODES.IO_ERROR, new Error('kbd int broken'));

// "FS_ERROR MyError: Broken vfat file-system"
MyError.createError(MyError.CODES.FS_ERROR, { fsName: 'vfat' });

// fails, because code IO_ERROR is not defined for Terror
Terror.createError(MyError.CODES.IO_ERROR);

ensureError(originalError, code)

Returns originalError if it's an instance of the owning class. Otherwise wrap originalError into new owning class instance using code or UNKNOWN_ERROR code if second argument is absent.

Example:

var MyError = Terror.create('MyError', {
        EMPTY_MESSAGE: 'Message string is empty',
        UNEXPECTED_ERROR: 'Unexpected error'
    }),
    arr = [ { msg: "hello" }, { msg: "" }, {} ];

arr.forEach(function(item) {
    try {
        if (item.msg.length > 0) {
            console.log(item.msg);
        } else {
            throw MyError.createError(MyError.CODES.EMPTY_MESSAGE);
        }
    } catch (err) {
        throw MyError.ensureError(err, MyError.CODES.UNEXPECTED_ERROR)
            .log(); // logging like MyError instance
    }
})

isTerror(error)

Checks whether the error is an instance of Terror class.

Example:

var err = new Error('average error here');
Terror.isTerror(err) === false;

var terr = Terror.ensureError(err);
Terror.isTerror(terr) === true;

is(code, error)

Checks whether the error is an instance of the context class and an error code equals the passed one.

Example:

var MyError = Terror.create('MyError', {
        XCODE: 'code X',
        ZCODE: 'code Z'
    });

MyError.is(MyError.CODES.XCODE, MyError.createError(MyError.CODES.XCODE)); // => true
MyError.is(MyError.CODES.ZCODE, MyError.createError(MyError.CODES.XCODE)); // => false
MyError.is(MyError.CODES.XCODE, Terror.createError()); // => false

Methods of prototype

log(level)

Log error with specified level. If method called twice or more for the same instance, logger will be called by first log call only.

Arguments:

  • {*} [level=constructor.DEFAULT_LOG_LEVEL] – any type accepted by logger.

Example:

var Terror = require('terror'),
    terr;

Terror.DEFAULT_LOG_LEVEL = 'INFO';

try {
    console.lag("hello!");
} catch (err) {
    terr = Terror.ensureError(err);
    terr.log()
        .log('warn')
        .log('error');
}

terr will be logged once with 'INFO' error level.

bind(data)

Fill an error message with values from data object properties.

Arguments:

  • {Object} data – hash, where key is a placeholder name to be replaced, value – a data to replace with.

Example:

var IOError = Terror.create('MyError', {
        IO_ERROR: 'Broken IO pipe "%pipe%"'
    });

IOError.createError(IOError.CODES.IO_ERROR)
    .bind({ pipe: 'main bus' })
    .log('PANIC');
// or
IOError.createError(IOError.CODES.IO_ERROR, { pipe: 'main bus' })
    .log('PANIC');

Internal, but useful prototype methods

Following methods used by built-in logger routine, but may be useful for any simple text logger.

logMultilineError(message, level, logger)

Formats error message and calls logger(formattedMessage).

Formatting is optimized for output call-stacks to the text files and future grep through.

Format:

LEVEL CODE CLASS: MESSAGE
>>>>>   CALL STACK ROW 1
…
>>>>>   CALL STACK ROW N

Example:

ERROR UNKNOWN_ERROR Terror: Unknown error (TypeError: Object #<Console> has no method 'lag')
>>>>>     at repl:2:9
>>>>>     at REPLServer.self.eval (repl.js:110:21)
>>>>>     at repl.js:249:20
>>>>>     at REPLServer.self.eval (repl.js:122:7)
>>>>>     at Interface.<anonymous> (repl.js:239:12)
>>>>>     at Interface.EventEmitter.emit (events.js:95:17)
>>>>>     at Interface._onLine (readline.js:202:10)
>>>>>     at Interface._line (readline.js:531:8)
>>>>>     at Interface._ttyWrite (readline.js:754:14)
>>>>>     at ReadStream.onkeypress (readline.js:99:10)