Giter VIP home page Giter VIP logo

erroz's Introduction

erroz

Descriptive errors through metadata

Build Status

Typical strategies of parsing errors are fragile and couple code to the error messages. By defining error objects consistently, working with errors becomes predictable and efficient.

Features

  • arbitrary error metadata
  • templated error messages
  • stack traces
  • JSend format errors

Example

var erroz = require("erroz");

var DuplicateError = erroz({
    name: "Duplicate",
    code: "duplicate",
    statusCode: 409,
    template: "Resource %resource (%id) already exists"
});

// ...

throw new DuplicateError({ resource: "Unicorn", id: 1 });

/*
 throw new DuplicateError();
 ^
 Duplicate: Resource Unicorn (1) already exists
 at Object.<anonymous> (/erroz/examples/staticErrorMessage.js:14:7)
 at Module._compile (module.js:456:26)
 at Object.Module._extensions..js (module.js:474:10)
 at Module.load (module.js:356:32)
 at Function.Module._load (module.js:312:12)
 at Function.Module.runMain (module.js:497:10)
 at startup (node.js:119:16)
 at node.js:902:3
 */

Installation

npm install --save erroz

Defining errors

var errorDefinition = {
    name: "NotFound",
    template: "%resource (%id) not found"
};

var NotFoundError = erroz(errorDefinition);

errorDefinition object

Arbitrary data structure for metadata which will be available on every error instance. Some attributes have a special meaning which is why they are described below:

name string

The name displayed when the error is thrown.

message string

A static error message.

template string

A dynamic error message. Variable substitution from the data object is done with %<variable name>.

Throwing (with data object)

var data = { resource: "Unicorn", id: 1 };
throw new NotFoundError(data);
// Duplicate: Resource Unicorn (1) already exists

data object

A set of data to be used with the errorDefinition.template property.

Throwing (with error message)

var overrideMessage = "You are not authorized to eat my cookies";
throw new ForbiddenError(overrideMessage);
// Forbidden: You are not authorized to eat my cookies

overrideMessage string

A message to override errorDefinition.message or errorDefinition.template. Use of this option will set error.data to an empty object.

JSON

Errors can be converted to JSON with JSON.stringify().

var err = new DuplicateError({ resource: "Unicorn", id: 1 });
console.log(JSON.stringify(err));

/*
 {
    "name": "Duplicate",
    "code": "duplicate",
    "status": "fail",
    "statusCode": 409,
    "template": "Resource %resource (%id) already exists",
    "data": {
        "resource": "Unicorn",
        "id": 1
    },
    "message": "Resource Unicorn (1) already exists"
 }
 */

Custom JSON format

The AbstractError.toJSON method can be defined to customize the JSON format.

// Set a custom `toJSON` method for all errors
erroz.AbstractError.prototype.toJSON = function() {
    return {
        name: this.name,
        code: this.code
    };
};

console.log(JSON.stringify(err));
/*
 {
    "name": "Duplicate",
    "code": "duplicate"
 }
 */

error.toJSend()

Converts the error to a JSend-style object. The JSend status attribute is derived from the statusCode if not passed explicitly. Valid codes are 4xx and 5xx. In case of an invalid statusCode, .toJSend() will throw an error.

var err = new DuplicateError({ resource: "Unicorn", id: 1, status: 409 });

err.toJSend();

/*
 {
    "status": "fail",
    "code": "duplicate",
    "message": "Resource Unicorn (1) already exists",
    "data": {
    	"resource": "Unicorn",
    	"id": 1,
    	"stack": "Duplicate: Resource Unicorn (1) already exists\n    at Object.<anonymous> (/erroz/examples/				  toJson.js:13:11)\n    at Module._compile (module.js:				  456:26)\n    at Object.Module._extensions..js (module.js:474:10)\n    at Module.load 				  (module.js:356:32)\n    at Function.Module._load (module.js:312:12)\n    at 			     Function.Module.runMain (module.js:497:10)\n    at startup (node.js:119:16)\n    at node.js:				  906:3"
    	}
}
*/

Options

renderMessage function

Define a custom error renderer.

erroz.options.renderMessage = function(data, template) {
    return "Ooops";
}

includeStack boolean

Whether the stack should be included in errors. Default is true.

erroz.options.includeStack = false;

Consider turning this off in production and sending it to a logger instead.

Pro Tip: Using erroz with Connect / Express error handlers

Define a global error handler which calls toJSend() if the error is an instance of erroz.AbstractError. why do this? So you can simply next all your errors in your route-handlers.

function myAwesomeRoute(req, res, next) {
    if (!req.awesome) {
        next(new NotAwesomeError()); 
        return; 
    }

    next();
}	
app.use(function errozHandler(err, req, res, next) {
    if (err instanceof erroz.AbstractError) {
        res.status(err.statusCode).send(err.toJSend()); 
        return; 
    } 

    // Pass on all non-erroz errors
    next(err);
});

Licence

MIT

Sponsors

erroz's People

Contributors

benurb avatar karlhorky avatar meaku avatar sbat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

erroz's Issues

Helper for wrapped errors

Sometime it's useful to catch some known errors and convert them to erroz-errors. Unfortunately those errorz-erros have the stacktrace of erroz-creation. It might be helpful to add an option to pass an original error when creating an erroz-error instance to append the original error.

Something like:

var ParseError = erroz({
  statusCode: 400,
  status: "fail",
  name: "ParseError",
  code: "parse-error",
  template "Could not parse %what"
});

try{ 
  JSON.parse("xaz--");
}
catch(err) {
   //pass original err as second argument (optional)
   errozErr = new ParseError({ what: "ever" }, err); 

   console.log(errozErr.stack) //would equal err.stack    
 }

Although it seems convenient it's also confusing as the stack is not pointing to the real "throw" . Maybe it's possible to merge the stacks or introduce a second originalStack attribute.

How to handle mismatch between `status` and `statusCode`

How should we handle that:

erroz({
    status: "success",
    statusCode: 400
});

It is obvious that the status can be derived by the statusCode:

  • 2xx = "success"
  • 4xx = "fail"
  • 5xx = "error"

Maybe the user should just be able to set the statusCode.

Add git tags and/or a changelog

Hello there ๐Ÿ˜„

I tried to update erroz in one of our applications from 0.1.4 to 1.0.0 and it's really hard to find out which breaking change caused the major version bump. To me it's unclear which git commits were used to publish 0.1.4 and 1.0.0 to npm. Maybe you can make this a bit more clear ๐Ÿ‘

Ben

Detect error code collisions

Within the same application, there should not be more than one error class associated with a given error code. Erroz should detect these collisions and throw an error.

var FileNotFound = erroz({
    code: "not-found"
});
// Should throw an Duplicate error code error
var UserNotFound = erroz({
    code: "not-found"
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.