node錯誤處理與日志記錄的實現(xiàn)
node項目中的錯誤處理
node中Error對象的使用
使用captureStackTrace方法加入自帶的錯誤信息
// Error對象自帶的屬性 Error.captureStackTrace // 如何使用captureStackTrace var obj = { message: 'something is wrong' } Error.captureStackTrace(obj) throw obj // 此時會拋出obj對象的message內(nèi)信息
使用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方式來做錯誤處理比較容易麻煩,容易出錯,現(xiàn)在node已經(jīng)支持async await所以盡量使用它們準(zhǔn)沒錯
async function foo(){ try{ await bar() }catch(e){ console.log(e) } } async function bar(){ throw new Error('async function got wrong) } foo()
基本錯誤類型
在項目會有多個地方對錯誤信息進(jìn)行處理,所以先寫一個基本錯誤類型,方便使用
// 基本錯誤類型 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); }
特定錯誤類型
除了基本類型,不同情況下會有不同錯誤信息,需要用一個特定的錯誤類型來處理特定的錯誤信息
// 一個參數(shù)錯誤類型 const ERROR_CODE = 40000 // 錯誤碼 class HttpRequestParamError extends HttpBaseError { constructor(paramName, desc, msg) { super(200, desc, ERROR_CODE, `${paramName} wrong: ${msg}`) } }
這樣,在參數(shù)錯誤的地方就能非常方便的調(diào)用這個錯誤類型來返回錯誤
拋錯的邏輯
錯誤處理中,model,controller中的錯誤,有些是不能直接返回給用戶的,應(yīng)該只返回給model或controller的調(diào)用者。
使用錯誤處理
正常接口,controller,model的錯誤,使用設(shè)定好的錯誤類型進(jìn)行處理,例如前面寫的HttpRequestParamError,在所有所有路由的最后,需要使用一個error handler來對所有的錯誤進(jìn)行集中處理
// 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 { // 設(shè)定之外的錯誤,把管理權(quán)向外移交 next(err) } } }
除了可預(yù)知的錯誤,還有未知的類型的錯誤,此時需要一個unknow error handler進(jìn)行剩余錯誤的處理
function unKnowErrorHandler(options) { return function (err, req, res, next) { console.log(err) res.json({ code: 99999, msg: 'unKnow error' }) } }
node中的日志
平時使用console來debug是沒有問題的,但是在線上環(huán)境,我們并不能有效的看到console,使用日志系統(tǒng)可以更好的方便線上的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' // 設(shè)置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文件內(nèi)會記錄info級別的log和比info級別高的log,比如error logger.info('first info log with winston')
日志滾動(log rotation)
在產(chǎn)生大量數(shù)據(jù)的應(yīng)用當(dāng)中,日志的輸出是大量的,這是就需要對日志進(jìn)行拆分處理,例如按照每天的頻率來分別記錄日志。
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目錄下就生成了今天的日志
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于nodejs使用express創(chuàng)建web服務(wù)器的操作步驟
express實際上是對nodejs內(nèi)置http進(jìn)行封裝后的第三方包,其中提供了快捷創(chuàng)建web服務(wù)器以及處理請求路由的方法,使我們可以更加方便快捷的實現(xiàn)一個web服務(wù)器項目,本文件給大家詳細(xì)介紹基于nodejs使用express?創(chuàng)建web服務(wù)器的操作步驟2023-07-07Node解決簡單重復(fù)問題系列之Excel內(nèi)容的獲取
這篇文章主要給大家介紹了關(guān)于利用Node解決簡單重復(fù)問題系列之Excel內(nèi)容獲取的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧。2018-01-01express如何解決ajax跨域訪問session失效問題詳解
這篇文章主要給大家介紹了關(guān)于express如何解決ajax跨域訪問session失效問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06初識NodeJS服務(wù)端開發(fā)入門(Express+MySQL)
本篇文章主要介紹了初識NodeJS服務(wù)端開發(fā)入門(Express+MySQL),可以對數(shù)據(jù)庫中的一張表進(jìn)行簡單的CRUD操作,有興趣的可以了解一下。2017-04-04HTTP JSON接口模擬工具Interfake快速入門教程
這篇文章主要為大家介紹了HTTP JSON接口模擬工具Interfake快速入門教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06nodejs構(gòu)建本地web測試服務(wù)器 如何解決訪問靜態(tài)資源問題
這篇文章主要為大家詳細(xì)介紹了nodejs構(gòu)建本地web測試服務(wù)器,教大家如何解決訪問靜態(tài)資源問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07