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()
基本錯誤類型
在項目會有多個地方對錯誤信息進行處理,所以先寫一個基本錯誤類型,方便使用
// 基本錯誤類型
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è)定好的錯誤類型進行處理,例如前面寫的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 {
// 設(shè)定之外的錯誤,把管理權(quán)向外移交
next(err)
}
}
}
除了可預(yù)知的錯誤,還有未知的類型的錯誤,此時需要一個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是沒有問題的,但是在線上環(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)中,日志的輸出是大量的,這是就需要對日志進行拆分處理,例如按照每天的頻率來分別記錄日志。
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)文章
使用ExcelJS快速處理Node.js爬蟲數(shù)據(jù)
Excel.js是一個強大的JavaScript庫,它提供了方法處理Excel文件,例如創(chuàng)建和編輯工作簿、讀取和寫入數(shù)據(jù)、處理行和列、設(shè)置樣式、導(dǎo)入和導(dǎo)出數(shù)據(jù)等,本文介紹使用ExcelJS快速處理Node.js爬蟲數(shù)據(jù)的方法,一起看看吧2024-01-01
關(guān)于NodeJs和JAVA建立socket連接方式
這篇文章主要介紹了關(guān)于NodeJs和JAVA建立socket連接方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06

