iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
自我挑戰組

30 天 Node.js 探索:基礎、進階與實踐系列 第 15

Day 15: 錯誤處理與日誌管理

  • 分享至 

  • xImage
  •  

接下來要學習如何在 Node.js 中進行錯誤處理與日誌管理,提升應用程式的穩定性與可維護性。

為什麼錯誤處理和日誌管理很重要?

  • 錯誤處理: 無論應用程式多麼完善,還是有可能會發生錯誤。有完善的錯誤處理機制就可以防止應用崩潰,並提供有意義的錯誤訊息來幫助開發者迅速定位問題。
  • 日誌管理: 通過記錄日誌,開發者能夠追蹤應用程式的執行情況、錯誤訊息,甚至分析系統瓶頸,確保系統的穩定運行。

Node.js 中的錯誤類型

在 Node.js 中,錯誤大致可以分為兩類:

  • 同步錯誤: 在程式執行過程中立即被捕捉的錯誤,通常可以使用 try-catch 來處理。
  • 非同步錯誤: 由於 Node.js 是基於非同步的事件驅動架構,非同步操作的錯誤需要通過回調函數或 Promise 捕捉。

基本錯誤處理

使用 try-catch 捕捉同步錯誤

js
function divide(a, b) {
  try {
    if (b === 0) {
      throw new Error('Cannot divide by zero');
    }
    return a / b;
  } catch (err) {
    console.error('Error:', err.message);
  }
}

console.log(divide(4, 2));  // Output: 2
console.log(divide(4, 0));  // Output: Error: Cannot divide by zero

實際打入 Node.js ,執行結果會如下:
https://ithelp.ithome.com.tw/upload/images/20240927/20169444C4AfVqIEGg.png
try-catch 適用於同步程式中的錯誤捕捉。

處理非同步錯誤

在非同步程式中,例如回調函數或 Promise,需要不同的方式來處理錯誤。
使用回調函數處理錯誤:

js
const fs = require('fs');

fs.readFile('nonexistent.txt', 'utf8', (err, data) => {
  if (err) {
    return console.error('Error reading file:', err.message);
  }
  console.log(data);
});

實際打入 Node.js ,執行結果會如下:
https://ithelp.ithome.com.tw/upload/images/20240927/20169444IiFstJjT5p.png
使用 Promise 和 async/await 捕捉錯誤:

js
const fsPromises = require('fs').promises;

async function readFileAsync() {
  try {
    const data = await fsPromises.readFile('nonexistent.txt', 'utf8');
    console.log(data);
  } catch (err) {
    console.error('Error reading file:', err.message);
  }
}

readFileAsync();

實際打入 Node.js ,執行結果會如下:
https://ithelp.ithome.com.tw/upload/images/20240927/20169444ByDNIQ2f1a.png
async/await 配合 try-catch 可以流暢的處理非同步錯誤。

全域錯誤處理

若錯誤未被捕捉,可能導致應用崩潰。Node.js 提供了全域性的錯誤處理機制,幫助應用處理未預期的錯誤。
捕捉未處理的 Promise 錯誤:

js
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});

實際打入 Node.js ,執行結果會如下:
https://ithelp.ithome.com.tw/upload/images/20240927/20169444H8YyxYmXlv.png
捕捉未捕獲的異常:

js
process.on('uncaughtException', (err) => {
  console.error('Uncaught Exception:', err.message);
  // 可選:關閉應用程式
  process.exit(1);
});

實際打入 Node.js ,執行結果會如下:
https://ithelp.ithome.com.tw/upload/images/20240927/201694442TwJaTCG4w.png
這些全域處理機制應該僅作為最後的防線,在應用程式中還是要盡量處理好所有可預期的錯誤。

日誌管理

日誌管理是一個良好維護應用程式的關鍵。在 Node.js 中,可以使用專門的日誌套件來提升日誌管理的靈活性與可讀性。

使用 console 進行基本日誌管理

Node.js 內建的 console 是最簡單的日誌工具,可以用於開發和基本錯誤記錄。

js
console.log('This is an info log');
console.error('This is an error log');

然而,console 的功能有限,且難以進行更高級的日誌管理。

使用 winston 管理日誌

winston 是一個功能強大的 Node.js 日誌管理庫,可以記錄不同級別的日誌、將日誌儲存到文件,並支援不同的傳輸(例如文件、控制台、第三方服務)。
安裝 winston:

bash
npm install winston

配置 winston:

js
const winston = require('winston');

// 建立 logger
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' }),
  ],
});

// 若在開發環境,則同時輸出到控制台
if (process.env.NODE_ENV !== 'production') {
  logger.add(new winston.transports.Console({
    format: winston.format.simple(),
  }));
}

// 使用 logger 記錄日誌
logger.info('This is an info log');
logger.error('This is an error log');

實際運行 ,執行結果會如下:
https://ithelp.ithome.com.tw/upload/images/20240927/20169444P5cyeZ2p5m.png
在這個例子中,winston 可以將日誌輸出到文件(如 error.log 和 combined.log),並且在開發環境中會將日誌輸出到控制台。

日誌級別

在日誌管理中,通常會根據日誌的重要性分為不同的級別:

  • error: 表示應用程序錯誤,需要立即去注意。
  • warn: 表示警告,可能導致錯誤或不期望的行為。
  • info: 常規資訊,記錄應用程式的正常運行狀況。
  • debug: 詳細資訊,通常用於開發和偵錯階段。
    在 winston 中,可以根據應用程式的運行環境選擇不同的日誌級別來輸出適當的日誌訊息。

錯誤處理與日誌整合

最後實際將錯誤處理與日誌系統結合,記錄應用程式中的錯誤處理它們。

js
process.on('unhandledRejection', (reason, promise) => {
  logger.error(`Unhandled Rejection at: ${promise}, reason: ${reason}`);
  // 可選:關閉應用程式
  process.exit(1);
});

process.on('uncaughtException', (err) => {
  logger.error(`Uncaught Exception: ${err.message}`);
  // 可選:關閉應用程式
  process.exit(1);
});

總結

今天探討了如何在 Node.js 中處理錯誤並記錄日誌。通過合理的錯誤處理,可以讓應用在錯誤發生時保持穩定;而透過日誌管理,能夠追蹤應用程式的行為並快速診斷問題。在後續的開發中,這些概念和工具將大大提升應用程式的可維護性。


上一篇
Day 14:驗證與授權:JWT (JSON Web Token) 簡介
下一篇
Day 16:安全性最佳實踐:避免 SQL Injection 和 XSS
系列文
30 天 Node.js 探索:基礎、進階與實踐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言