摘要:并不自帶,需要引入庫運(yùn)行日志文件,此時(shí)在目錄下就生成了今天的日志歡迎訪問我的博客
node項(xiàng)目中的錯(cuò)誤處理 node中Error對(duì)象的使用
使用captureStackTrace方法加入自帶的錯(cuò)誤信息
// Error對(duì)象自帶的屬性 Error.captureStackTrace // 如何使用captureStackTrace var obj = { message: "something is wrong" } Error.captureStackTrace(obj) throw obj // 此時(shí)會(huì)拋出obj對(duì)象的message內(nèi)信息使用try catch捕獲錯(cuò)誤
直接把代碼寫在try catch中即可捕獲錯(cuò)誤信息
try{ throw new Error("oh no") }catch(e){ console.log(e) }
在異步代碼中,直接try catch是無法捕獲錯(cuò)誤信息的,可以使用如下方法
function foo(params, cb){ const error = new Error("something is wrong") if(error) cb(error) }
以上使用callback方式來做錯(cuò)誤處理比較容易麻煩,容易出錯(cuò),現(xiàn)在node已經(jīng)支持async await所以盡量使用它們準(zhǔn)沒錯(cuò)
async function foo(){ try{ await bar() }catch(e){ console.log(e) } } async function bar(){ throw new Error("async function got wrong) } foo()基本錯(cuò)誤類型
在項(xiàng)目會(huì)有多個(gè)地方對(duì)錯(cuò)誤信息進(jìn)行處理,所以先寫一個(gè)基本錯(cuò)誤類型,方便使用
// 基本錯(cuò)誤類型 class HttpBaseError extends Error { constructor(httpStatusCode, httpMsg, errCode, msg) { super(`HTTP ERROR: ${msg}`); this.httpStatusCode = httpStatusCode; this.httpMsg = httpMsg; this.errCode = errCode; } } try { // 直接拋出定義好的錯(cuò)誤即可 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); }特定錯(cuò)誤類型
除了基本類型,不同情況下會(huì)有不同錯(cuò)誤信息,需要用一個(gè)特定的錯(cuò)誤類型來處理特定的錯(cuò)誤信息
// 一個(gè)參數(shù)錯(cuò)誤類型 const ERROR_CODE = 40000 // 錯(cuò)誤碼 class HttpRequestParamError extends HttpBaseError { constructor(paramName, desc, msg) { super(200, desc, ERROR_CODE, `${paramName} wrong: ${msg}`) } }
這樣,在參數(shù)錯(cuò)誤的地方就能非常方便的調(diào)用這個(gè)錯(cuò)誤類型來返回錯(cuò)誤
拋錯(cuò)的邏輯錯(cuò)誤處理中,model,controller中的錯(cuò)誤,有些是不能直接返回給用戶的,應(yīng)該只返回給model或controller的調(diào)用者。
使用錯(cuò)誤處理正常接口,controller,model的錯(cuò)誤,使用設(shè)定好的錯(cuò)誤類型進(jìn)行處理,例如前面寫的HttpRequestParamError,在所有所有路由的最后,需要使用一個(gè)error handler來對(duì)所有的錯(cuò)誤進(jìn)行集中處理
// error handler function handler(options) { return function (err, req, res, next) { if (err instanceof HttpRequestParamError) { // 這里對(duì)不同的錯(cuò)誤做不同的處理 console.log("http request error") res.statusCode = err.httpStatusCode res.json({ code: err.errCode, msg: err.httpMsg }) } else { // 設(shè)定之外的錯(cuò)誤,把管理權(quán)向外移交 next(err) } } }
除了可預(yù)知的錯(cuò)誤,還有未知的類型的錯(cuò)誤,此時(shí)需要一個(gè)unknow error handler進(jìn)行剩余錯(cuò)誤的處理
function unKnowErrorHandler(options) { return function (err, req, res, next) { console.log(err) res.json({ code: 99999, msg: "unKnow error" }) } }node中的日志
平時(shí)使用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的類型 }), // 第二個(gè)logger,記錄error級(jí)別的log new winston.transports.File({ name: "error_logger", filename: "logs/error.log", level: "error" }) ] }); // error級(jí)別比info要高,error.log文件只會(huì)記錄error日志 logger.error("first error log with winston") // info文件內(nèi)會(huì)記錄info級(jí)別的log和比info級(jí)別高的log,比如error logger.info("first info log with winston")日志滾動(dòng)(log rotation)
在產(chǎn)生大量數(shù)據(jù)的應(yīng)用當(dāng)中,日志的輸出是大量的,這是就需要對(duì)日志進(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!");
運(yùn)行日志文件,此時(shí)在logs目錄下就生成了今天的日志
歡迎訪問我的博客
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/100337.html
摘要:日志規(guī)范一般前端開發(fā)同學(xué),對(duì)日志其實(shí)不太敏感,畢竟前端大多數(shù)情況下,不太關(guān)心日志。本文主要梳理了目前我們團(tuán)隊(duì)在開發(fā)中日志方面存在的問題,以及通過統(tǒng)一日志規(guī)范,希望達(dá)到什么樣的效果。日志格式字段日志格式統(tǒng)一采用,便于解析處理。nodejs 日志規(guī)范 一般前端開發(fā)同學(xué),對(duì)日志其實(shí)不太敏感,畢竟前端大多數(shù)情況下,不太關(guān)心日志。即使有,也可能調(diào)用一些第三方的統(tǒng)計(jì),比如百度統(tǒng)計(jì)或者別的等。在 Node...
摘要:調(diào)用函數(shù)執(zhí)行下一個(gè)中間件函數(shù)。然后,該中間件調(diào)用函數(shù)檢查文件是否存在。為了代碼更加清晰,你也可以將代碼改寫為另外,這里在調(diào)用函數(shù)是使用的是作為輸出選項(xiàng)。事實(shí)上,中間件有兩種類型。 原生 Node 的單一請(qǐng)求處理函數(shù),隨著功能的擴(kuò)張勢必會(huì)變的越來越難以維護(hù)。而 Express 框架則可以通過中間件的方式按照模塊和功能對(duì)處理函數(shù)進(jìn)行切割處理。這樣拆分后的模塊不僅邏輯清晰,更重要的是對(duì)后期維...
摘要:比如權(quán)限驗(yàn)證,比如異常處理,比如日志管理。但突然有一天在線上訪問自己的項(xiàng)目,發(fā)現(xiàn)頁面報(bào)錯(cuò)了,想知道為什么報(bào)錯(cuò)了,發(fā)現(xiàn)竟然沒有什么很好的方法,如果我沒有通過一個(gè)東西去記錄的話,所以日志管理這個(gè)時(shí)候就顯得尤為重要了。 第一次寫node項(xiàng)目,之前除了前端的腳手架構(gòu)建接觸過一些簡單的,所以總是碰到很多坑。比如權(quán)限驗(yàn)證,比如異常處理,比如日志管理。在看log4js使用方法的時(shí)候突然想到自己就可以...
摘要:好吧且不說抽象統(tǒng)一處理的事,解決問題才是目的。確實(shí)把整個(gè)錯(cuò)誤處理可以完整的抽象出來。當(dāng)然可以在中注入更多統(tǒng)一處理函數(shù),也可以通過函數(shù)名做一些判斷,比如對(duì)所有名字中包含的函數(shù)進(jìn)行單獨(dú)的日志處理。 起因 在之前的項(xiàng)目中我發(fā)現(xiàn)每個(gè)控制器大約都是這樣寫的 async function findId (id) { let res; try{ res = await...
摘要:將如下代碼寫入到文件中,并在環(huán)境里執(zhí)行如圖雖然這兩個(gè)輸出看起來可能一樣,但系統(tǒng)實(shí)際上對(duì)它的處理方式有不同。如圖如果你沒有啟動(dòng)調(diào)試日志,則不會(huì)看到任何這樣的日志輸出。 原文地址: https://www.twilio.com/blog/g...原文作者: DOMINIK KUNDEL 翻譯作者: icepy 翻譯出處: https://github.com/lightningm... ...
閱讀 918·2021-10-27 14:19
閱讀 1145·2021-10-15 09:42
閱讀 1567·2021-09-14 18:02
閱讀 765·2019-08-30 13:09
閱讀 3010·2019-08-29 15:08
閱讀 2113·2019-08-28 18:05
閱讀 977·2019-08-26 10:25
閱讀 2813·2019-08-23 16:28