我成為了 OpenClaw 的 Contributor
一個 type guard、一則 PR、一次 merge。從使用者到貢獻者,小企鵝的第一次開源貢獻紀錄。
一個 type guard、一則 PR、一次 merge。從使用者到貢獻者。
用 OpenClaw 也好一陣子了。每天跟 Pingu 在終端機裡協作,從寫文章、管專案、跑 cron、到整理健康數據,基本上我的數位生活有一半是在 OpenClaw 裡完成的。
用久了,自然會踩到一些邊角的 bug。
遇到 Bug
這個 bug 出現在 Telegram 整合的部分。OpenClaw 有個 describeReplyTarget 函式,負責解析 Telegram 訊息的 reply context——就是你回覆一則訊息時,被回覆的那則訊息的內容。
問題在於,Telegram API 回傳的 replyLike.text 不一定是字串。有時候它會是一個 ExternalReplyInfo 物件。但原本的程式碼直接對它呼叫 .trim():
const rawText = replyLike.text ?? replyLike.caption ?? "";
return rawText.trim(); // 如果 rawText 是物件 → TypeError
物件沒有 .trim() 方法,直接 TypeError 炸開。
修復
修法很簡單——一個 type guard:
const rawText = replyLike.text ?? replyLike.caption ?? "";
const safeText = typeof rawText === "string" ? rawText.trim() : "";
同一個函式裡,quoteText 其實已經用了一模一樣的 pattern。所以這不是什麼創新,就是把已有的防禦邏輯補到漏掉的地方。
補了一個 regression test,確保非字串值不會再炸:
// 傳入 text: { some: "object" } → 應該回傳 null,不是 throw
PR 提交
PR #50500,標題:
fix(telegram): add type guard for reply context text
提交之後,Greptile(自動 code review bot)給了 5/5 confidence:
“This PR is safe to merge — the change is minimal, correct, and well-tested.”
Maintainer @obviyus 在 3/23 直接 merge 進 main,留了一句:
“Thanks @p3nchan.”
沒有來回修改,沒有 request changes,一發就中。
感想
這是我第一次對一個有規模的開源專案提交 PR 並被 merge。
說實話,改動很小。就是一個 type guard、幾行程式碼。但從「使用者」變成「貢獻者」,這個身份轉換的感覺比程式碼本身重要太多了。
我相信好的開源貢獻往往就是這樣——不是要做什麼驚天動地的重構,而是在日常使用中發現問題,然後順手修掉。
你每天在用的工具,裡面可能就有一個小小的 bug 等著你去修。
認真玩,慢慢來。
小企鵝阿批 Penchan
由 Penchan 撰寫,Penna 協助編輯。