摘要:并不自帶,需要引入庫運行日志文件,此時在目錄下就生成了今天的日志歡迎訪問我的博客
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目錄下就生成了今天的日志
歡迎訪問我的博客
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/100337.html
摘要:日志規(guī)范一般前端開發(fā)同學(xué),對日志其實不太敏感,畢竟前端大多數(shù)情況下,不太關(guān)心日志。本文主要梳理了目前我們團(tuán)隊在開發(fā)中日志方面存在的問題,以及通過統(tǒng)一日志規(guī)范,希望達(dá)到什么樣的效果。日志格式字段日志格式統(tǒng)一采用,便于解析處理。nodejs 日志規(guī)范 一般前端開發(fā)同學(xué),對日志其實不太敏感,畢竟前端大多數(shù)情況下,不太關(guān)心日志。即使有,也可能調(diào)用一些第三方的統(tǒng)計,比如百度統(tǒng)計或者別的等。在 Node...
摘要:調(diào)用函數(shù)執(zhí)行下一個中間件函數(shù)。然后,該中間件調(diào)用函數(shù)檢查文件是否存在。為了代碼更加清晰,你也可以將代碼改寫為另外,這里在調(diào)用函數(shù)是使用的是作為輸出選項。事實上,中間件有兩種類型。 原生 Node 的單一請求處理函數(shù),隨著功能的擴(kuò)張勢必會變的越來越難以維護(hù)。而 Express 框架則可以通過中間件的方式按照模塊和功能對處理函數(shù)進(jìn)行切割處理。這樣拆分后的模塊不僅邏輯清晰,更重要的是對后期維...
摘要:比如權(quán)限驗證,比如異常處理,比如日志管理。但突然有一天在線上訪問自己的項目,發(fā)現(xiàn)頁面報錯了,想知道為什么報錯了,發(fā)現(xiàn)竟然沒有什么很好的方法,如果我沒有通過一個東西去記錄的話,所以日志管理這個時候就顯得尤為重要了。 第一次寫node項目,之前除了前端的腳手架構(gòu)建接觸過一些簡單的,所以總是碰到很多坑。比如權(quán)限驗證,比如異常處理,比如日志管理。在看log4js使用方法的時候突然想到自己就可以...
摘要:好吧且不說抽象統(tǒng)一處理的事,解決問題才是目的。確實把整個錯誤處理可以完整的抽象出來。當(dāng)然可以在中注入更多統(tǒng)一處理函數(shù),也可以通過函數(shù)名做一些判斷,比如對所有名字中包含的函數(shù)進(jìn)行單獨的日志處理。 起因 在之前的項目中我發(fā)現(xiàn)每個控制器大約都是這樣寫的 async function findId (id) { let res; try{ res = await...
摘要:將如下代碼寫入到文件中,并在環(huán)境里執(zhí)行如圖雖然這兩個輸出看起來可能一樣,但系統(tǒng)實際上對它的處理方式有不同。如圖如果你沒有啟動調(diào)試日志,則不會看到任何這樣的日志輸出。 原文地址: https://www.twilio.com/blog/g...原文作者: DOMINIK KUNDEL 翻譯作者: icepy 翻譯出處: https://github.com/lightningm... ...
閱讀 961·2021-10-27 14:19
閱讀 1184·2021-10-15 09:42
閱讀 1615·2021-09-14 18:02
閱讀 800·2019-08-30 13:09
閱讀 3046·2019-08-29 15:08
閱讀 2156·2019-08-28 18:05
閱讀 1009·2019-08-26 10:25
閱讀 2851·2019-08-23 16:28