node项目中的毛病处置惩罚
node中Error对象的运用
运用captureStackTrace
要领到场自带的毛病信息
// Error对象自带的属性
Error.captureStackTrace
// 怎样运用captureStackTrace
var obj = {
message: 'something is wrong'
}
Error.captureStackTrace(obj)
throw obj // 此时会抛出obj对象的message内信息
运用try catch捕捉毛病
直接把代码写在try catch
中即可捕捉毛病信息
try{
throw new Error('oh no')
}catch(e){
console.log(e)
}
在异步
代码中,直接try catch是没法捕捉毛病信息的,能够运用以下要领
function foo(params, cb){
const error = new Error('something is wrong')
if(error) cb(error)
}
以上运用callback
体式格局来做毛病处置惩罚比较轻易贫苦,轻易失足,如今node已支撑async await
所以只管运用它们准没错
async function foo(){
try{
await bar()
}catch(e){
console.log(e)
}
}
async function bar(){
throw new Error('async function got wrong)
}
foo()
基础毛病范例
在项目会有多个处所对毛病信息举行处置惩罚,所以先写一个基础毛病
范例,轻易运用
// 基础毛病范例
class HttpBaseError extends Error {
constructor(httpStatusCode, httpMsg, errCode, msg) {
super(`HTTP ERROR: ${msg}`);
this.httpStatusCode = httpStatusCode;
this.httpMsg = httpMsg;
this.errCode = errCode;
}
}
try {
// 直接抛出定义好的毛病即可
throw new HttpBaseError(404, '资本不存在', 10000, 'resouse is not found');
} catch (e) {
console.log(e.message);
console.log(e.httpStatusCode);
console.log(e.httpMsg);
console.log(e.errCode);
}
特定毛病范例
除了基础范例,差别情况下会有差别毛病信息,须要用一个特定
的毛病范例来处置惩罚特定的毛病信息
// 一个参数毛病范例
const ERROR_CODE = 40000 // 毛病码
class HttpRequestParamError extends HttpBaseError {
constructor(paramName, desc, msg) {
super(200, desc, ERROR_CODE, `${paramName} wrong: ${msg}`)
}
}
如许,在参数毛病的处所就可以异常轻易的挪用这个毛病范例来返回毛病
抛错的逻辑
毛病处置惩罚中,model,controller中的毛病,有些是不能直接返回给用户的,应当只返回给model或controller的挪用者。
运用毛病处置惩罚
一般接口,controller,model的毛病,运用设定好的毛病范例举行处置惩罚,比方前面写的HttpRequestParamError
,在一切一切路由的末了,须要运用一个error handler来对一切的毛病举行集合处置惩罚
// error handler
function handler(options) {
return function (err, req, res, next) {
if (err instanceof HttpRequestParamError) { // 这里对差别的毛病做差别的处置惩罚
console.log('http request error')
res.statusCode = err.httpStatusCode
res.json({
code: err.errCode,
msg: err.httpMsg
})
} else {
// 设定以外的毛病,把管理权向外移交
next(err)
}
}
}
除了可预知的毛病,另有未知的范例的毛病,此时须要一个unknow error handler举行盈余毛病的处置惩罚
function unKnowErrorHandler(options) {
return function (err, req, res, next) {
console.log(err)
res.json({
code: 99999,
msg: 'unKnow error'
})
}
}
node中的日记
日常平凡运用console来debug是没有问题的,但是在线上环境,我们并不能有用的看到console,运用日记体系能够更好的轻易线上的debug,纪录信息等
winston的运用
winston
是node中经常使用的日记插件
const winston = require('winston')
const logger = winston.createLogger({
transports: [
new winston.transports.Console(),
new winston.transports.File({
name: 'info_logger', // log称号
filename: 'logs/info.log', // 日记纪录文件地点
level: 'info' // 设置log的范例
}),
// 第二个logger,纪录error级别的log
new winston.transports.File({
name: 'error_logger',
filename: 'logs/error.log',
level: 'error'
})
]
});
// error级别比info要高,error.log文件只会纪录error日记
logger.error('first error log with winston')
// info文件内会纪录info级别的log和比info级别高的log,比方error
logger.info('first info log with winston')
日记转动(log rotation)
在发生大批数据的运用当中,日记的输出是大批的,这是就须要对日记举行拆分
处置惩罚,比方根据天天的频次来离别纪录日记。
winston并不自带log rotation,须要引入winston-daily-rotate-file
库
const {
createLogger,
format,
transports
} = require('winston');
const {
combine,
timestamp,
label,
prettyPrint
} = format;
require('winston-daily-rotate-file')
var transport = new(transports.DailyRotateFile)({
filename: './logs/app-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH',
maxSize: '20m',
maxFiles: '14d',
format: combine(
label({
label: 'right meow!'
}),
timestamp(),
prettyPrint()
),
});
transport.on('rotate', function (oldFilename, newFilename) {});
var logger = createLogger({
transports: [
transport
]
});
logger.info('Hello World!');
运行日记文件,此时在logs目录下就生成了本日的日记
迎接接见我的博客