提交 ead8980193480e4883695e1f5ccba5f992202958

作者 Nick Baugh
1 个父辈 da79e1b5

Fixed error handler

@@ -219,6 +219,12 @@ var errorHandler = IoC.create('igloo/error-handler') @@ -219,6 +219,12 @@ var errorHandler = IoC.create('igloo/error-handler')
219 219
220 app.post('/user', createUser, errorHandler) 220 app.post('/user', createUser, errorHandler)
221 221
  222 +// you could also do:
  223 +// app.post('/user', createUser)
  224 +// app.use(errorHandler)
  225 +// but make sure that `app.use(errorHandler)`
  226 +// is the very last route middleware to be `use`'d
  227 +
222 function createUser(req, res, next) { 228 function createUser(req, res, next) {
223 229
224 if (!_.isString(req.body.name)) 230 if (!_.isString(req.body.name))
@@ -3,112 +3,114 @@ @@ -3,112 +3,114 @@
3 3
4 var mergeDefaults = require('merge-defaults') 4 var mergeDefaults = require('merge-defaults')
5 var _ = require('underscore') 5 var _ = require('underscore')
  6 +var _str = require('underscore.string')
  7 +_.mixin(_str.exports())
6 var util = require('util') 8 var util = require('util')
7 9
8 exports = module.exports = function(logger, settings) { 10 exports = module.exports = function(logger, settings) {
9 11
10 - return function() { 12 + return function(err, req, res, next) {
11 13
12 - var app = this 14 + // set default error status code
  15 + res.statusCode = (_.isNumber(err.status)) ? err.status : 500
13 16
14 - app.use(function(err, req, res, next) { 17 + if (!_.isString(err.message))
  18 + err.message = 'An unknown error has occured, please try again'
15 19
16 - // set default error status code  
17 - res.statusCode = (_.isNumber(err.status)) ? err.status : 500 20 + if (_.isObject(err) && _.isNumber(err.code) && err.code === 11000) {
  21 + // <https://github.com/LearnBoost/mongoose/issues/2129>
  22 + var field = err.message.split('index: ')[1].split('.$')[1]
  23 + // now we have `email_1 dup key`
  24 + field = field.split(' dup key')[0]
  25 + field = field.substring(0, field.lastIndexOf('_'))
  26 + err.message = util.format('Duplicate %s already exists in database, try making a more unique value', field)
  27 + err.param = field
  28 + }
18 29
19 - if (!_.isString(err.message))  
20 - err.message = 'An unknown error has occured, please try again' 30 + // if we pass an error object, then we want to simply return the message...
  31 + // if we pass an object, then we want to do a stack trace, and then return the object + stack
  32 + var error = {}
21 33
22 - if (_.isObject(err) && _.isNumber(err.code) && err.code === 11000) {  
23 - // <https://github.com/LearnBoost/mongoose/issues/2129>  
24 - var field = err.message.split('index: ')[1].split('.$')[1]  
25 - // now we have `email_1 dup key`  
26 - field = field.split(' dup key')[0]  
27 - field = field.substring(0, field.lastIndexOf('_'))  
28 - err.message = util.format('Duplicate %s already exists in database, try making a more unique value', field)  
29 - err.param = field  
30 - }  
31 -  
32 - // if we pass an error object, then we want to simply return the message...  
33 - // if we pass an object, then we want to do a stack trace, and then return the object + stack  
34 - var error = {}  
35 -  
36 - // set error type  
37 - error.type = res.statusCode < 500 ? 'invalid_request_error' : 'api_error'  
38 -  
39 - if (_.isString(err.param)) {  
40 - error.type = 'invalid_request_error'  
41 - if (res.statusCode === 500)  
42 - res.statusCode = 400  
43 - }  
44 -  
45 - /*  
46 - error.type = _.isString(err.param) ? 'invalid_request_error' : 'api_error'  
47 -  
48 - if (error.type === 'invalid_request_error' && res.statusCode === 500)  
49 - res.statusCode = 400  
50 - */  
51 -  
52 - // set error message and stack trace  
53 - if (util.isError(err)) {  
54 - error.message = err.message  
55 - } else {  
56 - _.extend(error, err)  
57 - } 34 + // set error type
  35 + error.type = res.statusCode < 500 ? 'invalid_request_error' : 'api_error'
58 36
59 - // set status code for BadRequestError  
60 - if (_.isString(error.name) && error.name === 'BadRequestError') {  
61 - error.type = 'invalid_request_error' 37 + if (_.isString(err.param)) {
  38 + error.type = 'invalid_request_error'
  39 + if (res.statusCode === 500)
62 res.statusCode = 400 40 res.statusCode = 400
63 - delete error.name  
64 - }  
65 -  
66 - if (settings.showStack)  
67 - error.stack = _.isUndefined(err.stack) ? new Error(err.message).stack : err.stack  
68 -  
69 - // set error level  
70 - var level = (res.statusCode < 500) ? 'warn' : 'error'  
71 -  
72 - // if we have a mongoose validation err  
73 - // then we know to output all the errors  
74 - if (_.isObject(error.errors) && !_.isEmpty(error.errors)) {  
75 - var messages = []  
76 - _.each(error.errors, function(errMsg) {  
77 - if (_.isString(errMsg.message))  
78 - messages.push(errMsg.message)  
79 - })  
80 - if (!_.isEmpty(messages))  
81 - error.message = messages.join(' ')  
82 - }  
83 -  
84 - res.format({  
85 - text: function() {  
86 - res.send(error.message)  
87 - },  
88 - html: function() {  
89 - // set error back to warning if it was warn  
90 - // logger level type = "warn"  
91 - // req.flash messages type = "warning"  
92 - req.flash(level === 'warn' ? 'warning' : level, error.message)  
93 - res.redirect('back')  
94 - },  
95 - json: function() {  
96 - res.json({ error: error }) 41 + }
  42 +
  43 + /*
  44 + error.type = _.isString(err.param) ? 'invalid_request_error' : 'api_error'
  45 +
  46 + if (error.type === 'invalid_request_error' && res.statusCode === 500)
  47 + res.statusCode = 400
  48 + */
  49 +
  50 + // set error message and stack trace
  51 + if (util.isError(err)) {
  52 + error.message = err.message
  53 + } else {
  54 + _.extend(error, err)
  55 + }
  56 +
  57 + // set status code for BadRequestError
  58 + if (_.isString(error.name) && error.name === 'BadRequestError') {
  59 + error.type = 'invalid_request_error'
  60 + res.statusCode = 400
  61 + delete error.name
  62 + }
  63 +
  64 + if (settings.showStack)
  65 + error.stack = _.isUndefined(err.stack) ? new Error(err.message).stack : err.stack
  66 +
  67 + // set error level
  68 + var level = (res.statusCode < 500) ? 'warn' : 'error'
  69 +
  70 + // if we have a mongoose validation err
  71 + // then we know to output all the errors
  72 + if (_.isObject(err.errors) && !_.isEmpty(err.errors)) {
  73 + var messages = []
  74 + _.each(err.errors, function(errMsg) {
  75 + // <https://github.com/syntagma/mongoose-error-helper/blob/master/lib/mongoose-error-helper.js>
  76 + // TODO: add support for enum, min, and max?
  77 + if (_.isString(errMsg.type) && errMsg.type === 'required' && _.isString(errMsg.path)) {
  78 + messages.push(util.format('%s is required', _.humanize(errMsg.path)))
  79 + } else if (_.isString(errMsg.message)) {
  80 + messages.push(errMsg.message)
97 } 81 }
98 }) 82 })
99 -  
100 - if (_.isObject(req.log)) {  
101 - req.log.response_time = new Date().getTime() - req.log.response_time  
102 - req.log.status = res.statusCode  
103 - req.log.response_type = res.get('Content-Type')  
104 - req.log.response_body = error  
105 - } else {  
106 - req.log = error 83 + if (!_.isEmpty(messages)) {
  84 + error.message = messages.join(', ')
  85 + }
  86 + }
  87 +
  88 + res.format({
  89 + text: function() {
  90 + res.send(error.message)
  91 + },
  92 + html: function() {
  93 + // set error back to warning if it was warn
  94 + // logger level type = "warn"
  95 + // req.flash messages type = "warning"
  96 + req.flash(level === 'warn' ? 'warning' : level, error.message)
  97 + res.redirect('back')
  98 + },
  99 + json: function() {
  100 + res.json({ error: error })
107 } 101 }
  102 + })
108 103
109 - logger[level](error.message, req.log) 104 + if (_.isObject(req.log)) {
  105 + req.log.response_time = new Date().getTime() - req.log.response_time
  106 + req.log.status = res.statusCode
  107 + req.log.response_type = res.get('Content-Type')
  108 + req.log.response_body = error
  109 + } else {
  110 + req.log = error
  111 + }
110 112
111 - }) 113 + logger[level](error.message, req.log)
112 114
113 } 115 }
114 116
@@ -36,13 +36,14 @@ @@ -36,13 +36,14 @@
36 "express-session": "^1.2.1", 36 "express-session": "^1.2.1",
37 "merge-defaults": "^0.1.0", 37 "merge-defaults": "^0.1.0",
38 "nodemailer": "^1.3.0", 38 "nodemailer": "^1.3.0",
  39 + "slack-winston": "^0.0.1",
39 "to-camel-case": "^0.2.1", 40 "to-camel-case": "^0.2.1",
40 "underscore": "^1.6.0", 41 "underscore": "^1.6.0",
  42 + "underscore.string": "^2.3.3",
41 "update-notifier": "^0.2.0", 43 "update-notifier": "^0.2.0",
42 "winston": "git://github.com/niftylettuce/winston", 44 "winston": "git://github.com/niftylettuce/winston",
43 "winston-hipchat": "^0.1.1", 45 "winston-hipchat": "^0.1.1",
44 - "winston-mongodb": "~0.4.3",  
45 - "slack-winston": "^0.0.1" 46 + "winston-mongodb": "~0.4.3"
46 }, 47 },
47 "devDependencies": { 48 "devDependencies": {
48 "chai": "^1.9.1", 49 "chai": "^1.9.1",
注册登录 后发表评论