node错误处理与日记

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目录下就生成了本日的日记
迎接接见我的博客

    原文作者:李诺
    原文地址: https://segmentfault.com/a/1190000017487731
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞