node错误处理与日志记录的实现


Posted in Javascript onDecember 24, 2018

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目录下就生成了今天的日志

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery内部原理和实现方式浅析
Feb 03 Javascript
QQ登录背景闪动效果附效果演示源码下载
Sep 22 Javascript
JavaScript严格模式详解
Nov 18 Javascript
Javascript实现倒计时(防页面刷新)实例
Dec 13 Javascript
vue利用better-scroll实现轮播图与页面滚动详解
Oct 20 Javascript
Angular6 正则表达式允许输入部分中文字符
Sep 10 Javascript
微信小程序实现日历功能
Nov 27 Javascript
微信小程序出现wx.getLocation再次授权问题的解决方法分析
Jan 16 Javascript
基于Vue全局组件与局部组件的区别说明
Aug 11 Javascript
vue3+typescript实现图片懒加载插件
Oct 26 Javascript
vue 动态添加class,三个以上的条件做判断方式
Nov 02 Javascript
如何基于viewport vm适配移动端页面
Nov 13 Javascript
详解如何在vscode里面调试js和node.js的方法步骤
Dec 24 #Javascript
@angular前端项目代码优化之构建Api Tree的方法
Dec 24 #Javascript
微信小程序获取用户openid的实现
Dec 24 #Javascript
vue-router启用history模式下的开发及非根目录部署方法
Dec 23 #Javascript
小程序实现人脸识别功能(百度ai)
Dec 23 #Javascript
优雅的elementUI table单元格可编辑实现方法详解
Dec 23 #Javascript
基于webpack4.X从零搭建React脚手架的方法步骤
Dec 23 #Javascript
You might like
新手学PHP之数据库操作详解及乱码解决!
2007/01/02 PHP
生成随机字符串和验证码的类的PHP实例
2013/12/24 PHP
PHP用mb_string函数库处理与windows相关中文字符及Win环境下开启PHP Mb_String方法
2015/11/11 PHP
PHP实现求解最长公共子串问题的方法
2017/11/17 PHP
js之事件冒泡和事件捕获详细介绍
2013/10/28 Javascript
用html5 js实现点击一个按钮达到浏览器全屏效果
2014/05/28 Javascript
javascript实现动态模态绑定grid过程代码
2014/09/22 Javascript
简单总结JavaScript中的String字符串类型
2016/05/26 Javascript
使用JavaScript实现表格编辑器(实例讲解)
2017/08/02 Javascript
Vue.js 踩坑记之双向绑定
2018/05/03 Javascript
vue自动化表单实例分析
2018/05/06 Javascript
js实现全选反选不选功能代码详解
2019/04/24 Javascript
node.js实现上传文件功能
2019/07/15 Javascript
es6中Promise 对象基本功能与用法实例分析
2020/02/23 Javascript
解决vue项目,npm run build后,报路径错的问题
2020/08/13 Javascript
js+canvas实现刮刮奖功能
2020/09/13 Javascript
js实现三角形粒子运动
2020/09/22 Javascript
[01:06:54]DOTA2-DPC中国联赛 正赛 SAG vs DLG BO3 第二场 2月28日
2021/03/11 DOTA
python中pass语句用法实例分析
2015/04/30 Python
用python做一个搜索引擎(Pylucene)的实例代码
2017/07/05 Python
Python rstrip()方法实例详解
2018/11/11 Python
Python实现统计英文文章词频的方法分析
2019/01/28 Python
python 实现selenium断言和验证的方法
2019/02/13 Python
python数据预处理之数据标准化的几种处理方式
2019/07/17 Python
python支付宝支付示例详解
2019/08/22 Python
django admin管理工具自定义时间区间筛选器DateRangeFilter介绍
2020/05/19 Python
python安装和pycharm环境搭建设置方法
2020/05/27 Python
浅谈pandas dataframe对除数是零的处理
2020/07/20 Python
Html5上传图片 移动端、PC端通用代码
2016/06/08 HTML / CSS
使用HTML5 Canvas API中的clip()方法裁剪区域图像
2016/03/25 HTML / CSS
Wedgwood英国官方网站:英式精致骨瓷餐具、礼品与生活精品,源于1759年
2019/09/02 全球购物
美国亚马逊旗下时尚女装网店:SHOPBOP(支持中文)
2020/10/17 全球购物
会计电算化大学生职业规划书
2014/02/05 职场文书
晚自修旷课检讨书怎么写
2014/11/17 职场文书
小学英语复习计划
2015/01/19 职场文书
2019最新企业员工考勤管理制度(通用版)!
2019/07/02 职场文书