资讯专栏INFORMATION COLUMN

node错误处理与日志

GT / 514人阅读

摘要:并不自带,需要引入库运行日志文件,此时在目录下就生成了今天的日志欢迎访问我的博客

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://www.ucloud.cn/yun/100337.html

相关文章

  • Node.js + ELK 日志规范

    摘要:日志规范一般前端开发同学,对日志其实不太敏感,毕竟前端大多数情况下,不太关心日志。本文主要梳理了目前我们团队在开发中日志方面存在的问题,以及通过统一日志规范,希望达到什么样的效果。日志格式字段日志格式统一采用,便于解析处理。nodejs 日志规范 一般前端开发同学,对日志其实不太敏感,毕竟前端大多数情况下,不太关心日志。即使有,也可能调用一些第三方的统计,比如百度统计或者别的等。在 Node...

    tuomao 评论0 收藏0
  • Express 实战(四):中间件

    摘要:调用函数执行下一个中间件函数。然后,该中间件调用函数检查文件是否存在。为了代码更加清晰,你也可以将代码改写为另外,这里在调用函数是使用的是作为输出选项。事实上,中间件有两种类型。 原生 Node 的单一请求处理函数,随着功能的扩张势必会变的越来越难以维护。而 Express 框架则可以通过中间件的方式按照模块和功能对处理函数进行切割处理。这样拆分后的模块不仅逻辑清晰,更重要的是对后期维...

    mochixuan 评论0 收藏0
  • 实现node日志管理

    摘要:比如权限验证,比如异常处理,比如日志管理。但突然有一天在线上访问自己的项目,发现页面报错了,想知道为什么报错了,发现竟然没有什么很好的方法,如果我没有通过一个东西去记录的话,所以日志管理这个时候就显得尤为重要了。 第一次写node项目,之前除了前端的脚手架构建接触过一些简单的,所以总是碰到很多坑。比如权限验证,比如异常处理,比如日志管理。在看log4js使用方法的时候突然想到自己就可以...

    sevi_stuo 评论0 收藏0
  • node端统一错误处理

    摘要:好吧且不说抽象统一处理的事,解决问题才是目的。确实把整个错误处理可以完整的抽象出来。当然可以在中注入更多统一处理函数,也可以通过函数名做一些判断,比如对所有名字中包含的函数进行单独的日志处理。 起因 在之前的项目中我发现每个控制器大约都是这样写的 async function findId (id) { let res; try{ res = await...

    kaka 评论0 收藏0
  • Node.js 日志输出指南

    摘要:将如下代码写入到文件中,并在环境里执行如图虽然这两个输出看起来可能一样,但系统实际上对它的处理方式有不同。如图如果你没有启动调试日志,则不会看到任何这样的日志输出。 原文地址: https://www.twilio.com/blog/g...原文作者: DOMINIK KUNDEL 翻译作者: icepy 翻译出处: https://github.com/lightningm... ...

    csRyan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<