CodeGym /課程 /SQL SELF /建立 error_log 資料表來自動記錄錯誤

建立 error_log 資料表來自動記錄錯誤

SQL SELF
等級 52 , 課堂 2
開放

想像一下,你在跟資料庫打交道,處理一堆 transaction,結果突然出包。用戶抱怨、老闆在吼,但你根本不知道發生什麼事。這時候正確的錯誤記錄就超重要啦。它可以:

  • 把錯誤存進資料庫,方便之後分析。
  • 很容易還原錯誤細節:發生時間、訊息、還有相關資料。
  • 分析 log 之後,針對常見錯誤優化你的 code。

簡單說,log 就像是你資料庫的監視器錄影帶:所有出錯的時刻和原因都能看到。

建立 error_log 資料表

我們就從基礎開始吧。要先建立一個資料表來存錯誤資訊。這個 table 會有以下欄位:

  • id — 錯誤的唯一識別碼。
  • error_message — 錯誤訊息內容。
  • error_time — 發生錯誤的時間。
  • (可選)context — 錯誤的 context,如果你想存更多細節。
CREATE TABLE error_log (
    id SERIAL PRIMARY KEY,        -- 錯誤的唯一識別碼
    error_message TEXT NOT NULL,  -- 錯誤訊息內容
    error_time TIMESTAMP NOT NULL DEFAULT NOW(), -- 發生錯誤的時間
    context JSONB                 -- 錯誤的額外資料
);

這段 code 在做什麼?

  • id SERIAL PRIMARY KEY — 這個欄位會自動產生每筆記錄的唯一 id。
  • error_message TEXT NOT NULL — 這裡會存錯誤訊息,必填。
  • error_time TIMESTAMP NOT NULL DEFAULT NOW() — 記錄事件發生的時間。如果沒給值,會自動用 DEFAULT NOW() 寫入現在時間。
  • context JSONB — 可選欄位,存放像是哪個操作出錯等額外資訊。

執行 CREATE TABLE 後,你的資料庫就有一個專門存 log 的結構啦。

錯誤寫入資料表的範例

table 建好後,來點實作:把錯誤資訊寫進 table。我們來寫個 function,把錯誤訊息和時間存進 error_log

寫入錯誤的 function 範例

CREATE OR REPLACE FUNCTION log_error(p_error_message TEXT, p_context JSONB DEFAULT NULL)
RETURNS VOID AS $$
BEGIN
    INSERT INTO error_log (error_message, context)
    VALUES (p_error_message, p_context);
END;
$$ LANGUAGE plpgsql;
  1. p_error_message — 傳入的參數,用來放錯誤訊息。
  2. p_context — 可選參數,傳遞額外資料。預設是 NULL
  3. INSERT INTO error_log (error_message, context) — 新增一筆錯誤記錄到 error_log
  4. DEFAULT NULL — 如果沒給 context,這欄就會是 NULL

現在要寫錯誤訊息時,你可以這樣呼叫 function:

SELECT log_error('執行查詢時發生錯誤', '{"query": "SELECT * FROM data"}');

這樣就會在 error_log table 新增一筆記錄。

自動錯誤記錄

每次都手動 SELECT log_error(...) 很麻煩。我們來用 exception 處理自動化這流程。

這裡有個帶 exception 處理的 function 範例。

CREATE OR REPLACE FUNCTION divide_numbers(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    result NUMERIC;
BEGIN
    -- 嘗試做除法
    result := a / b;

    -- 回傳結果
    RETURN result;
EXCEPTION
    WHEN division_by_zero THEN
        -- 記錄錯誤並傳遞 context
        PERFORM log_error('除以零', jsonb_build_object('a', a, 'b', b));
        -- 丟出 exception 給用戶
        RAISE EXCEPTION '無法將 % 除以 % — 除數是零', a, b;
END;
$$ LANGUAGE plpgsql;
  1. 除法檢查:執行 result := a / b。如果 b = 0,PostgreSQL 會丟出 division_by_zero exception。
  2. exception 處理器EXCEPTION)會攔截這個錯誤。
  3. 在 handler 裡我們呼叫 log_error,把錯誤和參數寫進 table。
  4. 寫完錯誤後,用 RAISE EXCEPTION 再丟出一個錯誤訊息,讓用戶也知道。

呼叫範例:

SELECT divide_numbers(10, 0);

結果:

  • 用戶會看到錯誤:無法將 10 除以 0 — 除數是零
  • error_log table 也會多一筆除以零的記錄。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION