正在显示
3 个修改的文件
包含
101 行增加
和
92 行删除
@@ -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", |
请
注册
或
登录
后发表评论