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 相关文章推荐
javascript解三阶幻方(九宫格)
Apr 22 Javascript
JavaScript使用FileSystemObject对象写入文本文件内容的方法
Aug 05 Javascript
BootStrap文件上传样式超好看【持续更新】
May 10 Javascript
JS中script标签defer和async属性的区别详解
Aug 12 Javascript
基于JavaScript实现图片剪切效果
Mar 07 Javascript
JS验证input输入框(字母,数字,符号,中文)
Mar 23 Javascript
二维码图片生成器QRCode.js简单介绍
Aug 18 Javascript
超出JavaScript安全整数限制的数字计算BigInt详解
Jun 24 Javascript
使用vue 国际化i18n 实现多实现语言切换功能
Oct 11 Javascript
微信小程序顶部导航栏滑动tab效果
Jan 28 Javascript
node.js使用express框架进行文件上传详解
Mar 03 Javascript
Vue.set 全局操作简单示例
Sep 19 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
全国FM电台频率大全 - 9 上海市
2020/03/11 无线电
php引用地址改变变量值的问题
2012/03/23 PHP
PHP的new static和new self的区别与使用
2019/11/27 PHP
innerText和textContent对比及使用介绍
2013/02/27 Javascript
jquery 快速回到页首的方法
2013/12/05 Javascript
Javascript中的delete操作符详细介绍
2014/06/06 Javascript
JavaScript日期时间与时间戳的转换函数分享
2015/01/31 Javascript
JavaScript检测浏览器cookie是否已经启动的方法
2015/02/27 Javascript
深入理解JavaScript系列(40):设计模式之组合模式详解
2015/03/04 Javascript
jquery实现简单的轮换出现效果实例
2015/07/23 Javascript
Web打印解决方案之证件套打的实现思路
2016/08/29 Javascript
js方法数据验证的简单实例
2016/09/17 Javascript
vuex 解决报错this.$store.commit is not a function的方法
2018/12/17 Javascript
微信小程序之 catalog 切换实现解析
2019/09/12 Javascript
[54:41]2018DOTA2亚洲邀请赛3月30日 小组赛B组 VGJ.T VS paiN
2018/03/31 DOTA
python类中super()和__init__()的区别
2016/10/18 Python
Python 数据结构之旋转链表
2017/02/25 Python
python去掉空白行的多种实现代码
2018/03/19 Python
使用PyCharm创建Django项目及基本配置详解
2018/10/24 Python
django2笔记之路由path语法的实现
2019/07/17 Python
Python3从零开始搭建一个语音对话机器人的实现
2019/08/23 Python
Pandas+Matplotlib 箱式图异常值分析示例
2019/12/09 Python
Python threading模块condition原理及运行流程详解
2020/10/05 Python
CSS3实现头像旋转效果
2017/03/13 HTML / CSS
Waterford美国官网:爱尔兰水晶制品品牌
2017/04/26 全球购物
TIME时代杂志台湾总代理:台时亚洲
2018/10/22 全球购物
Sneaker Studio罗马尼亚网站:购买运动鞋
2018/11/04 全球购物
天逸系统(武汉)有限公司Java笔试题
2015/12/29 面试题
什么是表空间(tablespace)和系统表空间(System tablespace)
2013/02/25 面试题
船舶专业个人求职信范文
2014/01/02 职场文书
乐观大学生的自我评价
2014/01/10 职场文书
《莫泊桑拜师》教学反思
2014/04/23 职场文书
我爱读书演讲稿
2014/05/07 职场文书
2014年结对帮扶工作总结
2014/12/17 职场文书
幼儿教师辞职信
2015/02/27 职场文书
2015年思想品德教学工作总结
2015/07/22 职场文书