Giter Site home page Giter Site logo

nodeerrors's Introduction

nodeerrors

This is a library for handling errors more efficiently in node.js, especially made for people like me who use function hoisting most of the time to avoid some of the so-called "callback hell".

Build Status NPM version Dependency Status Coverage Status

Installation

npm install nodeerrors

Specifying you own errors

You specify your own error types by adding the file .errors.js in the root folder of your project or in config/.errors.js. Here is an example of a .errors.js file:

module.exports = {
	"system":{
		message:"Internal server error",
		http:500
	},
	"notUnique":{
		message:"The property \"%s\" is not unique. The value \"%s\" already exists.",
		args:["propertyName", "propertyValue"],
		http:400
	},
	"propertyNotDefined":{
		message:"The property named \"%s\" should be defined",
		args:["propertyName"],
		http:400
	}
};

with the file above, you will be able to use your own errors like this:

var errors = require("nodeerrors");

callback(errors.notUnique("someProperty", "somePropertyValue")); //call callback with 'notUnique' error

Notice that errors.notUnique takes the two parameters propertyName and propertyValue as defined in the args property above.

Also these two parameters are automatically inserted into the error message where there is a %s.

You will also be able to do like this:

var errors = require("nodeerrors");

callback(errors.propertyNotDefined("someProperty")); //call callback with 'propertyNotDefined' error

Notice that propertyNotDefined only takes a single argument, because there is only one argument defined in args. You can even leave out args altogether, if your error does not take arguments.

Parsing errors

When you want an error to JSON.stringify-able (handle cyclic references), you should parse it with the parse function.

  • The parse function is useful when you want to log the error to a service like loggly.com or similar.
  • The parse function is useful if you want to return an error message to the client from an API. If you parse the error and remove the properties stack and internal everything else should be safe to send to the client. You can also remove the property http and use it for a http status code in your response.

If you are passed an error in your own callback, you can parse it like this:

var errors = require("nodeerrors");

function (err, data){
	if(err){
		errorObject = errors.parse(err);
		//...
	}
}

The errorObject variable will now contain

{
	"code": "propertyNotDefined",
	"http": 400,
	"propertyName": "someProperty",
	"message": "The property named \"someProperty\" should be defined",
	"stack": "[call stack of Error]",
	"id": "1cbf5dab-4630-4d09-b779-2c721e571859",
	"internal": {
		//...
	}
}

Note that you can parse any error, also errors passed to you from third party libraries. Errors from third party libraries are wrapped in a system error, and the original error will be in internal.innerError. This is done, in order not to pass sensitive internal error information to the client. After you parse an error, all you need to do is remove the stack and internal properties, everything else should be safe to send to the client.

Also note that each when parsing an error it will be given a uuid in the property id (if it does not already have a id-property). You can use this when you log the error and want to look up a specific error.

Adding extra internal values

You can always add an extra parameter, when you create an error. So if we take the propertyNotDefined example from above, that took only one parameter, we can do this:

var errors = require("nodeerrors");

callback(errors.propertyNotDefined(
	"someProperty",
	{notice:"This should NEVER happen"} //extra internal parameter
));

This extra parameter will be added to the errors internal parameter. So when we parse the error:

var errors = require("nodeerrors");

function (err, data){
	if(err){
		//...
	}
}

The err variable will now contain:

{
	"code": "propertyNotDefined",
	"http": 400,
	"propertyName": "someProperty",
	"message": "The property named \"someProperty\" should be defined",
	"stack": "[call stack of Error]"
	"id": "1cbf5dab-4630-4d09-b779-2c721e571859"
	"internal": {
		"notice":"This should NEVER happen"
	}
}

Note, you should always pass JSON serializable objects as the extra parameter.

innerError

When you are passed an error, you sometimes wrap it in your own error, perhaps grouping different error types into one kind of error you return. When you do this, you can save the original error using .innerError on the Error object (Error.prototype has been extended). So you can do something like this:

var errors = require("nodeerrors");
var errorCodes = errors.errorCodes;

function handleDocument(err, document){
	if(err){
		if(err.code = errorCodes.fileNotFound){
 			return callback(errors.mySpecialError().innerError(err));
 		}
 		return callback(err);
 	}
}

This returns a mySpecialError with the fileNotFound error as an inner error.

onError

Instead of writing

return mongoCollection.findOne({}, handleDocument);

function handleDocument(err, document){
	if(err){
    	return callback(err);
	}
    //...
}

After you require nodeerrors anywhere (Function.prototype has been extended), you can write:

return mongoCollection.findOne({}, handleDocument.onError(callback));

function handleDocument(err, document){
    //...
}

If findOne returns an error, it will automatically be sent to callback. You no longer need to handle the error in the handleDocument function, it will always be falsy (probably null)

Try catch is inserted around the function that has onError called. This means that the following code will not result in an uncaught exception. Instead the error will be passed to callback, for error handling.

return mongoCollection.findOne({}, handleDocument.onError(callback));

function handleDocument(err, document){
    throw new Error("some error");
}

Express compatible error handling middleware

TBA :-)

nodeerrors's People

Contributors

eagleeye avatar ebdrup avatar greenkeeperio-bot avatar jmosbech avatar jonatanpedersen avatar philipshurpik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

nodeerrors's Issues

License?

Let's say you, strictly hypothetical of course, wanted to use this in a commercial product. What terms would apply?

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.