」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Node.js 應用程式中的錯誤處理和日誌記錄

Node.js 應用程式中的錯誤處理和日誌記錄

發佈於2024-11-09
瀏覽:128

Error Handling and Logging in Node.js Applications

介绍

在后端开发领域,可靠的错误处理和结构化日志记录对于构建有弹性和可维护的应用程序至关重要。 Node.js 中有效的错误处理不仅可以改善用户体验,还可以简化调试并增强应用程序监控。结合适当的日志记录,开发人员可以更快地跟踪问题并实时监控系统运行状况。在本文中,我们将深入探讨 Node.js 中的错误处理和日志记录策略,这些策略可以使应用程序更加健壮并可用于生产。

1.了解 Node.js 中的错误处理

Node.js 中的错误处理有其独特的挑战,主要是由于其异步、事件驱动的架构。让我们探讨 Node.js 中有效错误处理的一些关键区别和原则:

  • 同步与异步错误:同步错误立即发生,可以使用传统的 try-catch 块捕获,而异步错误稍后发生,需要不同的处理,例如回调、承诺或异步/等待模式。
  • 统一错误处理策略:通过大量的异步操作,维护统一的方法有助于更有效地管理整个应用程序中的错误。一致的错误处理简化了调试并确保统一传播和记录错误。

2.基本错误处理技术

Node.js 提供了多种管理错误的机制,特别是在异步工作流程中:

  • Try-Catch 块:这些对于处理同步代码中的错误很有用,但不会捕获异步代码中的错误。例如:
  try {
    const data = JSON.parse(jsonString);
  } catch (error) {
    console.error("JSON parsing error:", error);
  }
  • 错误对象:Node.js 中的错误对象携带堆栈跟踪等重要信息,可以帮助开发人员调试问题。自定义错误消息应该清晰且可操作。

  • Promises 和 Async/Await 中的错误处理:

    • Promises:使用 .catch() 处理 Promise 拒绝。
    fetchData()
      .then(data => console.log(data))
      .catch(error => console.error("Error fetching data:", error));
    
    • Async/Await:将await 调用包装在try-catch 块内以进行异步错误处理。
    async function fetchData() {
      try {
        const data = await someAsyncFunction();
        console.log(data);
      } catch (error) {
        console.error("Error:", error);
      }
    }
    
  • 全局错误处理

    • 未捕获的异常:使用process.on('uncaughtException',callback)捕获未捕获的异常。
    • 未处理的拒绝:使用 process.on('unhandledRejection',callback) 处理未处理的 Promise 拒绝。这提供了生产中的最后一道防线,尽管通常建议在错误发生的地方进行处理。

3.高级错误处理模式

为了实现更具可扩展性和可维护性的错误处理,这些先进技术至关重要:

  • Express 中的中间件错误处理: Express 提供了内置的错误处理机制,可以捕获错误并将其传递给自定义中间件。
  app.use((err, req, res, next) => {
    console.error("Error:", err);
    res.status(500).send("Something went wrong!");
  });
  • 集中错误管理: 可以创建集中式错误处理模块来定义自定义错误响应和消息,从而提供处理错误的标准化方法。
  class AppError extends Error {
    constructor(message, statusCode) {
      super(message);
      this.statusCode = statusCode;
      Error.captureStackTrace(this, this.constructor);
    }
  }
  • 错误代码及分类: 使用 HTTP 状态代码对错误进行分类(4xx 表示客户端错误,5xx 表示服务器错误),并添加自定义代码以进行更详细的日志记录和错误跟踪。

4.在 Node.js 中实现日志记录

日志记录可以深入了解应用程序中发生的情况,对于跟踪错误非常有价值。以下是如何在 Node.js 中实现有效的日志记录:

  • 基本控制台日志记录:
    控制台对象(console.log、console.error 等)很方便,但在生产中受到限制。对于结构化、基于级别的日志记录,最好使用专用的日志记录库。

  • 使用 Winston 进行日志记录:
    Winston 是一个功能强大的日志记录库,提供结构化日志记录,包括信息、警告、错误和调试等级别。

  const winston = require("winston");

  const logger = winston.createLogger({
    level: "info",
    format: winston.format.json(),
    transports: [
      new winston.transports.File({ filename: "error.log", level: "error" }),
      new winston.transports.Console({ format: winston.format.simple() })
    ]
  });
  • 日志级别:

    • info:有关应用程序行为的一般信息。
    • warn:警告,通常是非破坏性但值得注意的事件。
    • 错误:需要立即关注的关键问题。
    • debug:对调试有用的详细信息。
  • 旋转日志:

    日志轮换限制日志文件大小并确保高效存储。 Winston 的 winston-daily-rotate-file 传输可以帮助管理每天的日志。

5.生产中的错误和日志管理

管理生产中的错误和日志需要额外考虑以维护性能和数据安全。

  • 使用日志服务:
    集成 LogglyPapertrailELK Stack(Elasticsearch、Logstash、Kibana)等服务以进行集中式日志管理。这些工具提供强大的搜索和过滤选项,可以快速解决生产问题。

  • 性能注意事项:
    日志记录会影响性能,因此请避免过多的日志记录,尤其是在高流量应用程序中。考虑为开发(调试)和生产(信息或错误)设置不同的日志级别。

  • 保护日志:
    为防止敏感信息泄露,请避免记录敏感数据,或使用脱敏技术对用户信息进行匿名化。

6。现实世界的例子

  • 电子商务应用程序:对于电子商务应用程序,记录用户操作并监控结帐过程中的错误可以深入了解用户行为和阻碍转化的问题。
  • 具有结构化日志记录的 REST API:使用结构化日志记录的 REST API 可以跟踪请求详细信息、错误和用户访问,从而帮助维护系统可靠性。

结论

总之,Node.js 中设计良好的错误处理和日志记录策略对于构建有弹性且可维护的应用程序至关重要。有效的错误处理和结构化日志记录使开发人员能够监视、排除故障和优化应用程序,确保他们准备好妥善处理错误并跟踪应用程序的运行状况。通过将这些技术与持续监控相结合,您将拥有一个更可靠的系统可供生产。

版本聲明 本文轉載於:https://dev.to/divine_nnanna2/error-handling-and-logging-in-nodejs-applications-1k2a?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何在 PHP 中組合兩個關聯數組,同時保留唯一 ID 並處理重複名稱?
    如何在 PHP 中組合兩個關聯數組,同時保留唯一 ID 並處理重複名稱?
    在 PHP 中組合關聯數組在 PHP 中,將兩個關聯數組組合成一個數組是常見任務。考慮以下請求:問題描述:提供的代碼定義了兩個關聯數組,$array1 和 $array2。目標是建立一個新陣列 $array3,它合併兩個陣列中的所有鍵值對。 此外,提供的陣列具有唯一的 ID,而名稱可能重疊。要求是建...
    程式設計 發佈於2024-11-17
  • 使用 Go Module 部署 Go Cloud Functions 時如何解決「Build failed: go: parsing /models/go.mod: open /models/go.mod: no such file or directory\」錯誤?
    使用 Go Module 部署 Go Cloud Functions 時如何解決「Build failed: go: parsing /models/go.mod: open /models/go.mod: no such file or directory\」錯誤?
    使用Go 模組部署Google Cloud Function 錯誤嘗試使用Go 模組在Go 1.11 中部署Google Cloud Function 時,開發者可能會遇到錯誤,「建置失敗:go:解析/models/go.mod:開啟/models/go.mod:沒有這樣的檔案或目錄。」Go模組結構...
    程式設計 發佈於2024-11-17
  • 大批
    大批
    方法是可以在物件上呼叫的 fns 數組是對象,因此它們在 JS 中也有方法。 slice(begin):將陣列的一部分提取到新數組中,而不改變原始數組。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index ...
    程式設計 發佈於2024-11-17
  • 為什麼我的 Golang `exec.Command` 回傳「退出狀態 1」?
    為什麼我的 Golang `exec.Command` 回傳「退出狀態 1」?
    如何找出Golang的exec.Command中出現「Exit Status 1」錯誤的原因在Golang中執行exec.Command方法時,收到「退出狀態1」錯誤可能會非常模糊。缺乏特定資訊會阻礙有效的調試。 要檢索更詳細的信息,請利用 Command 物件的 Stderr 屬性。這是透過以下方...
    程式設計 發佈於2024-11-17
  • 如何使用「setState」更新狀態中的巢狀物件?
    如何使用「setState」更新狀態中的巢狀物件?
    使用setState 更新state.item[1] 在這種情況下,您正在嘗試更新物件內的物件使用setState 在在您的狀態中。若要正確更新狀態,您需要複製整個狀態對象,修改副本,然後將狀態設定為更新後的副本。 以下是如何更新 state.item[1] 使用setState:// 1. Mak...
    程式設計 發佈於2024-11-17
  • Bootstrap 4 Beta 中的列偏移發生了什麼事?
    Bootstrap 4 Beta 中的列偏移發生了什麼事?
    Bootstrap 4 Beta:列偏移的刪除和恢復Bootstrap 4 在其Beta 1 版本中引入了重大更改柱子偏移了。然而,隨著 Beta 2 的後續發布,這些變化已經逆轉。 從 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    程式設計 發佈於2024-11-17
  • 將 PHP 連接到資料庫:MySQL 初學者
    將 PHP 連接到資料庫:MySQL 初學者
    在PHP 中連接到MySQL 資料庫至關重要,步驟如下:安裝MySQL 擴充功能使用mysqli_connect() 函數建立連接,參數包括主機、使用者名稱、密碼和資料庫名稱使用mysqli_connect_error() 函數檢查連接是否成功實戰案例:取得所有用戶,透過查詢資料庫並使用mysqli...
    程式設計 發佈於2024-11-17
  • 為什麼 CSS `visibility:hidden` 無法達到懸停效果?
    為什麼 CSS `visibility:hidden` 無法達到懸停效果?
    揭開謎團:為什麼CSS 可見性在懸停時失敗CSS 可見性提供了操作元素可見性的便捷方法,但有時它會偶然發現意想不到的障礙。考慮這樣一個場景,您定義了一個「擾流器」類別來使文字最初不可見,並在滑鼠懸停時顯示它。儘管您有期望,文字仍然頑固地保持在隱藏狀態,無視您的懸停努力。 深入探討原因這種令人困惑的行...
    程式設計 發佈於2024-11-17
  • 何時在 JavaScript 中使用 parseInt() 和 Number() 進行字串到數字的轉換?
    何時在 JavaScript 中使用 parseInt() 和 Number() 進行字串到數字的轉換?
    使用parseInt()和Number()將字串轉換為數字在JavaScript中將字串轉換為數字時,兩個常用的函數是parseInt () 和數字()。雖然它們都具有相同的數值轉換目的,但它們的方法和行為有所不同。 parseInt()parseInt() 執行更具體的任務,稱為解析。它嘗試從字串...
    程式設計 發佈於2024-11-17
  • 項目 避免不必要地使用檢查異常
    項目 避免不必要地使用檢查異常
    檢查異常是 Java 中的一個強大工具,因為它們迫使程式設計師處理異常情況,從而提高程式碼可靠性。然而,過度使用可能會導致 API 難以使用。為了證明檢查異常是合理的,情況必須是真正的異常並且程式設計師能夠採取有用的操作。否則,未經檢查的異常可能更合適。 Java 8 為檢查異常的使用帶來了額外的...
    程式設計 發佈於2024-11-17
  • 為什麼我的 PDO 更新查詢無法修改 MySQL 中的特定行?
    為什麼我的 PDO 更新查詢無法修改 MySQL 中的特定行?
    使用PDO 進行MySQL 更新查詢當嘗試使用PDO 和MySQL 更新資料庫行時,您可能會遇到這樣的情況:您的程式碼執行失敗。本指南探討了此錯誤的可能原因並提供了解決方案。 錯誤:不正確的 UPDATE 語法您遇到的錯誤源自於不正確的 UPDATE 語法。具體來說,您的查詢正在嘗試用提供的值替換 ...
    程式設計 發佈於2024-11-17
  • 資料庫遷移對於 Golang 服務,為什麼重要?
    資料庫遷移對於 Golang 服務,為什麼重要?
    DB Migration, why it matters? Have you ever faced the situations when you deploy new update on production with updated database schemas, but ...
    程式設計 發佈於2024-11-17
  • 在 Go 中使用 WebSocket 進行即時通信
    在 Go 中使用 WebSocket 進行即時通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    程式設計 發佈於2024-11-17
  • 為什麼在 Java 中連接空字串不會拋出 NullPointerException?
    為什麼在 Java 中連接空字串不會拋出 NullPointerException?
    Java 連接空字串在 Java 中,連接空字串可能看起來違反直覺,會導致 NullPointerException 出現。但是,此操作成功執行,結果是一個包含“null”的字串,後跟連接的字串。 為什麼會這樣? 根據 Java 語言規範(JLS) 8,§ 15.18.1,在字串連接期間,空引用明確...
    程式設計 發佈於2024-11-17
  • Java 正規表示式中的擷取群組如何運作?
    Java 正規表示式中的擷取群組如何運作?
    了解Java 正規表示式擷取群組在此程式碼片段中,我們使用Java 的正規表示式(regex) 函式庫來擷取字串的一部分。正規表示式定義為“(.)(\d )(.)”,其中:(.*):符合下一組之前的任意數量的任意字元.(\d ): 符合上一組之後的任意數量的數字。 (.*): 符合上一組之後的任意數...
    程式設計 發佈於2024-11-17

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3