This repository has been archived by the owner on Nov 24, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
262 additions
and
163 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = { | ||
name: 'badRequest', | ||
message: 'Bad request', | ||
status: 400 | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = { | ||
name: 'conflict', | ||
message: 'Conflict', | ||
status: 409 | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = { | ||
name: 'forbidden', | ||
message: 'Forbidden. You don\'t have permission to access this', | ||
status: 403 | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = { | ||
name: 'notFound', | ||
message: 'Oops! The page you requested doesn\'t exist', | ||
status: 404 | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = { | ||
name: 'unauthorized', | ||
message: 'Unauthorized', | ||
status: 401 | ||
}; |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1,130 @@ | ||
var fs = require('fs') | ||
, path = require('path') | ||
, basename = path.basename | ||
, defaultLogger | ||
, ex = {}; | ||
|
||
defaultLogger = function(err){ | ||
console.error(new Date().toLocaleString(), '>>', err); | ||
console.log(err.stack); | ||
} | ||
|
||
ex.define = function(opts){ | ||
var fn = function(){ | ||
this.message = opts.message; | ||
this.name = opts.name; | ||
this.status = opts.status; | ||
|
||
Error.call(this, this.message); | ||
Error.captureStackTrace(this, arguments.callee); | ||
} | ||
var fs = require('fs'), | ||
path = require('path'), | ||
pjoin = path.join, | ||
basename = path.basename, | ||
defaultLogger, | ||
hasOwn = Object.prototype.hasOwnProperty, | ||
ex = {}; | ||
|
||
fn.prototype.__proto__ = Error.prototype; | ||
ex.__defineGetter__(opts.name, function(){ | ||
return new fn(); | ||
}); | ||
ERRORS_DIR = pjoin(__dirname, 'errors'); | ||
|
||
return fn; | ||
} | ||
function Errors(app, config) { | ||
config || (config = { }); | ||
|
||
ex.bind = function(app, opts){ | ||
if(!opts) opts = {}; | ||
opts.logger || (opts.logger = defaultLogger); | ||
app.set('view engine') || | ||
(config.plain = true); | ||
|
||
if(!app.set('view engine')) opts.plain = true; | ||
config.list || (config.list = [ | ||
'badRequest', | ||
'conflict', | ||
'forbidden', | ||
'notFound', | ||
'unauthorized' | ||
]); | ||
|
||
if(opts.lastRoute == undefined || opts.lastRoute == true) { | ||
app.use(function(req, res, next){ | ||
next(ex.NotFound); | ||
}); | ||
} | ||
|
||
app.use(function(err, req, res, next){ | ||
if(!err.name || err.name == 'Error' || !ex.hasOwnProperty(err.name)){ | ||
opts.logger(err); | ||
|
||
if(req.xhr || opts.plain) | ||
return res.send({ error: 'Internal error' }, 500); | ||
|
||
return res.render('errors/500', { | ||
layout: opts.layout, | ||
status: 500, | ||
error: err, | ||
showStack: app.settings.showStackError, | ||
title: 'Oops! Something went wrong!' | ||
}); | ||
} | ||
this._logger = config.logger || this._defaultLogger; | ||
this._config = config; | ||
|
||
if(req.xhr) return res.send({ error: err.message }, err.status); | ||
|
||
if(opts.plain){ | ||
res.send(err.message, err.status); | ||
} else { | ||
res.render('errors/' + err.status, { | ||
layout: opts.layout, | ||
status: err.status, | ||
error: err, | ||
showStack: app.settings.showStackError, | ||
title: err.message | ||
}); | ||
} | ||
this._app = app; | ||
|
||
}); | ||
this._errors = { }; | ||
this._loadErrors(config.list); | ||
|
||
return ex; | ||
this._bind(); | ||
} | ||
|
||
// | ||
// Loading errors | ||
// | ||
|
||
var httpErrors = __dirname + '/http'; | ||
|
||
fs.readdir(httpErrors, function(err, files){ | ||
if(err) throw new Error(err); | ||
|
||
files.forEach(function(file){ | ||
if(file.charAt(0) == '.') return; | ||
Errors.prototype.get = function(key) { | ||
return key? | ||
this._errors[key] : | ||
this._errors; | ||
}; | ||
|
||
Errors.prototype.set = function(key, decl) { | ||
this._errors[key] = this._create(decl); | ||
return this; | ||
}; | ||
|
||
Errors.prototype.unset = function(key) { | ||
delete this._errors[key]; | ||
return this; | ||
}; | ||
|
||
Errors.prototype._create = function(decl) { | ||
var Fn = function() { | ||
Object.keys(decl).forEach(function(key) { | ||
this[key] = decl[key]; | ||
}, this); | ||
|
||
Error.call(this, this.message); | ||
Error.captureStackTrace(this, Fn); | ||
}; | ||
|
||
Fn.prototype = Error.prototype; | ||
|
||
return Fn; | ||
}; | ||
|
||
Errors.prototype._loadErrors = function(list) { | ||
list.forEach(function(item) { | ||
var decl; | ||
|
||
try { | ||
decl = require(pjoin(ERRORS_DIR, item)); | ||
} catch(e) { | ||
if (e.code === 'MODULE_NOT_FOUND') { | ||
decl = require(item); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
|
||
this.set(decl.name, decl); | ||
}, this); | ||
}; | ||
|
||
Errors.prototype._defaultLogger = { | ||
error: function(err) { | ||
console.error(new Date().toLocaleString(), '>>', err); | ||
console.log(err.stack); | ||
} | ||
}; | ||
|
||
Errors.prototype._bind = function() { | ||
var errors = this.get(), | ||
config = this._config, | ||
logger = this._logger, | ||
app = this._app; | ||
|
||
app.use(function(err, req, res, next) { | ||
if(!err.name || err.name == 'Error' || !hasOwn.call(errors, err.name)) { | ||
logger.error(err); | ||
res.status(500); | ||
|
||
if(req.xhr || config.plain) | ||
return res.send({ error: 'Internal error' }); | ||
|
||
return res.render('errors/500', { | ||
layout: config.layout, | ||
error: err, | ||
showStack: app.settings.showStackError, | ||
title: 'Oops! Something went wrong!' | ||
}); | ||
} | ||
|
||
res.status(err.status); | ||
|
||
if(req.xhr) return res.send({ error: err.message }); | ||
|
||
config.plain? | ||
res.send(err.message) : | ||
res.render((config.errorViews || 'errors') + '/' + err.status, { | ||
layout: config.layout, | ||
error: err, | ||
showStack: app.settings.showStackError, | ||
title: err.message | ||
}); | ||
|
||
var opts = require(httpErrors + '/' + file); | ||
opts.name = basename(file, '.json'); | ||
ex.define(opts); | ||
}); | ||
}); | ||
}); | ||
}; | ||
|
||
module.exports = ex; | ||
module.exports = Errors; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,7 @@ | ||
[![build status](https://secure.travis-ci.org/corpix/express-errors.png)](http://travis-ci.org/corpix/express-errors) | ||
##### Express errors | ||
|
||
Available in NPM `npm install express-errors` | ||
|
||
Provides easy access to common http errors for express e.g. | ||
|
||
* 400 - Bad request | ||
* 401 - Unathorized | ||
* 403 - Forbidden | ||
* 404 - NotFound | ||
* 409 - Conflict | ||
* 500 - Internal server error | ||
|
||
--- | ||
#### Example | ||
You need create `views/errors` directory and add 401,403,404 error views. | ||
|
||
```javascript | ||
var logger; | ||
app.get('/400', function(req, res, next){ | ||
next(errors.BadRequest); // You will get "bad request" error | ||
}); | ||
|
||
app.get('/500', function(req, res, next){ | ||
next(new Error('Something went wrong :(')); // You will get "Internal server error" error | ||
}); | ||
|
||
var errors = require('express-errors'); | ||
|
||
logger = function(err){ // Custom logger function | ||
console.error(err); | ||
} | ||
errors.bind(app, { layout: false, logger: logger }); // IMPORTANT! Call it after all routes ready | ||
``` | ||
|
||
#### Options | ||
Currently this options are available: | ||
|
||
* `lastRoute` - if false `express-errors` will not maintain last app.use route(NotFound error) | ||
* `plain` - if app.settings['view engine'] is undefined OR this option is presented res.send instead of res.render will be used | ||
* `logger` - custom logger function | ||
|
||
#### Defining an error | ||
Yeah, you can. Use .define method: | ||
|
||
```javascript | ||
errors.define({ | ||
name: 'BadRequest', // You will be able to access it through `errors.BadRequest` in future | ||
message: 'Bad request', // This message for XHR requests | ||
status: 400 // HTTP status | ||
}); | ||
``` | ||
|
||
#### TODO | ||
|
||
* More options | ||
Look at the tests for docs until I will find time to write something here ;) |
Oops, something went wrong.