Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 46 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,87 +2,66 @@

Ever tried to create custom error types in Node.js and wished it should be this simple?

```
var MyError = Error.extend('MyError');
```
var MyError = extend(Error, 'MyError');
throw MyError('wow')

```
throw MyError('wow')
```
### Installation

### installation
npm install tangxinfa/extend-error

```
npm install extend-error
```
#### Test

and in your app.js, just ```require('extend-error')```. It will provide you an extend() method for the Error type.
npm test

### Documentation

/**
* extend Error type.
*
* @param BaseError base error type to extend. Must be Error or subclass of Error.
* @param extendedErrorOptions extended error type options.
* Object:
* - name [required] string, extended error type name.
* - message [optional] string, default error message.
* - toString [optional] function, overwrite toString method.
* String: extended error type name.
* @return Extended error type.
*/
function extend(BaseError, extendedErrorOptions)

### syntax
- extend() takes two arguments : subTypeName & errorCode [optional]
- it returns the newly created error type
/**
* CodedError type
* - name: CodedError
* - code: Error code.
*/
var CodedError = extend(Error, {...});

### Examples for a web app

### more examples for a web app
#### Extend error types

var http = require('http');
var util = require('util');
var extend = require('extend-error');

something useful
var AppError = extend(Error, "AppError");
var NotFound = extend(extend.CodedError, {name: 'NotFoundError', message: http.STATUS_CODES[404], code: 404});
var InternalServerError = extend(extend.CodedError, {name: 'InternalServerError', message: http.STATUS_CODES[500], code: 500});

```
var AppError = Error.extend('AppError', 500);
var ClientError = Error.extend('ClientError', 400);
```
#### Throw errors

extend ClientError further for specific http types
throw new NotFound({resource: '/subject/1'});

```
var HttpNotFound = ClientError.extend('HttpNotFoundError', 404);
var HttpUnauthorized = ClientError.extend('HttpUnauthorized', 401);
```
// 'new' keyword is optional.
throw InternalServerError();

### throwing errors
// compitable with raw Error constructor.
throw InternalServerError('connection closed);

```
throw new AppError('unable to connect db due to error: ' + err);

throw new ClientError({'message':'required field missing', field: 'email'})

throw new HttpNotFound('no post found with id: ' + id);

throw new HttpNotFound({'message': 'no such post', 'id': id});
```

### don't worry when you forget 'new'

```
throw ClientError('bad request');
```

### instanceof

throw an error in controller

```
var err = HttpNotFound('user profile not found');

throw err;
(or)
callback(err)
```

handle it easily in global error handler (in case of express.js error middleware)

```
if (err instanceof ClientError) {
//send out the actual message
res.send(err.code, err.message);
} else {
//send out a generic message
res.send(500, 'oops! something went wrong');
log.error(err);
}

```
#### Handle errors

if (err instanceof NotFound) {
res.send(err.code, "Please create subject(" + err.resource + ") first.");
} else {
res.send(err.code, err.message);
}
26 changes: 0 additions & 26 deletions http-errors.js

This file was deleted.

48 changes: 3 additions & 45 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,5 @@
var util = require('util');
var assert = require('assert');
var extend = require('./lib/extend');
extend.CodedError = require('./lib/CodedError');


/**
* Add extend() method to Error type
*
* @param subTypeName
* @param errorCode [optional]
* @returns {SubType}
*/

Error.extend = function(subTypeName, errorCode /*optional*/) {
assert(subTypeName, 'subTypeName is required');

//define new error type

var SubType = (function(message) {
//handle constructor call without 'new'
if (! (this instanceof SubType)) {
return new SubType(message);
}

//populate error details
this.name = subTypeName;
this.code = errorCode;
this.message = message || '';

//include stack trace in error object
Error.captureStackTrace(this, this.constructor);
});

//inherit the base prototype chain
util.inherits(SubType, this);


//override the toString method to error type name and inspected message (to expand objects)
SubType.prototype.toString = function() {
return this.name + ': ' + util.inspect(this.message);
};

//attach extend() to the SubType to make it extendable further
SubType.extend = this.extend;

return SubType;
};

module.exports = extend;
19 changes: 19 additions & 0 deletions lib/CodedError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
var extend = require('./extend.js');
var util = require('util');


/**
* CodedError type
* - name: CodedError
* - code: Error code.
*/
var CodedError = extend(Error, {
name: 'CodedError',
code: undefined,
toString: function () {
return this.name + ' ' + this.code + (typeof(this.message) == 'undefined' ? '' : ': ' + util.inspect(this.message));
}
});


module.exports = CodedError;
75 changes: 75 additions & 0 deletions lib/extend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
var util = require('util');
var assert = require('assert');


/**
* extend Error type.
*
* @param BaseError base error type to extend. Must be Error or subclass of Error.
* @param extendedErrorOptions extended error type options.
* Object:
* - name [required] string, extended error type name.
* - message [optional] string, default error message.
* - toString [optional] function, overwrite toString method.
* String: extended error type name.
* @return Extended error type.
*/
function extend(BaseError, extendedErrorOptions) {
assert(BaseError.prototype instanceof Error || BaseError === Error, 'BaseError must be Error type');

if (typeof(extendedErrorOptions) == 'string') {
extendedErrorOptions = {name: extendedErrorOptions};
}

assert(extendedErrorOptions.name, 'Extended error type name is required');

if (! extendedErrorOptions.toString) {
// override the toString method to error type name and inspected message (to expand objects)
extendedErrorOptions.toString = function() {
return this.name + (typeof(this.message) == 'undefined' ? '' : ': ' + util.inspect(this.message));
};
}

// define extended error type.
var ExtendedError = (function(objectOptions) {
// handle constructor call without 'new'
if (! (this instanceof ExtendedError)) {
return new ExtendedError(objectOptions);
}

// compitable with Error constructor.
if (util.isPrimitive(objectOptions)) {
if (typeof(objectOptions) == 'undefined') {
objectOptions = {};
} else {
objectOptions = {message: objectOptions};
}
}

// assign object options.
for(var optionName in objectOptions) {
if (objectOptions.hasOwnProperty(optionName)) {
this[optionName] = objectOptions[optionName];
}
}

//include stack trace in error object
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
});

// inherit the base prototype chain
util.inherits(ExtendedError, BaseError);

// assign prototype options.
for(var optionName in extendedErrorOptions) {
if (extendedErrorOptions.hasOwnProperty(optionName)) {
ExtendedError.prototype[optionName] = extendedErrorOptions[optionName];
}
}

return ExtendedError;
}

module.exports = extend;
33 changes: 16 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
{
"name": "extend-error",
"version": "0.0.2",
"description": "Easily define custom error types in Node.js",
"main": "index.js",
"scripts": {
"test": "node_modules/.bin/mocha --reporter spec"
},
"author": "Jayy Vis <jayyvis@gmail.com>",
"devDependencies": {
"mocha": "*"
},
"repository": {
"type" : "git",
"url" : "http://github.com/jayyvis/extend-error.git"
},
"license": "MIT"
"name": "extend-error",
"version": "0.0.2",
"description": "Easily define custom error types in Node.js",
"main": "index.js",
"scripts": {
"test": "node_modules/.bin/mocha --reporter spec"
},
"author": "tangxinfa <tangxinfa@gmail.com>",
"devDependencies": {
"mocha": "*"
},
"repository": {
"type" : "git",
"url" : "http://github.com/tangxinfa/extend-error.git"
},
"license": "MIT"
}

Loading