Daily Tech Briefing
AI 科技速览

每天 5 分钟内学习 AI。获取最新的人工智能新闻,理解其重要性,并学习如何将其应用于您的工作。

AI 快讯
Dev.to AI · 2026/8/3 03:40:24

My Comment-Reply Script's Only Network Call Had Zero except Blocks. I'd Already Fixed This Exact Bug in a Different File.

AI 中文解读
开发者写了个自动回复评论的小程序,结果发现核心代码一直没加"安全网"——最关键的API请求部分既没有异常捕获也没有备用方案,一旦网络卡顿就会直接崩溃。更讽刺的是,他承认之前在另一个文件里修过同样的bug,却漏掉了这一处。 简单来说,这个脚本每天定时帮他在DEV.to文章下查漏补缺,找出还没回复的评论,并预生成回复草稿。但程序里调接口的部分就像在没系安全绳的情况下走钢丝——所有逻辑都依赖这次请求必须成功,否则整个流程就瘫了。正常情况下接口没事,可一旦网络抖动或者接口临时出问题,程序就会当场挂掉,而且没人发现,因为这是无人值守的定时任务。 这件事给普通程序员的启示很直接:稳定的代码不是靠运气,而是靠老老实实处理各种意外情况。哪怕一个看起来简单的请求,也应该做好出错准备。尤其是自动化脚本,平时运行得好不算本事,关键要看出了异常能不能优雅处理。这次教训也提醒我们,同样的坑可能藏在代码库的不同角落,修bug时最好全局搜索一下类似写法,别修一个漏一个。
<p>This repo runs a small unattended pipeline for replying to comments on my DEV.to articles. DEV.to's API won't let a normal account key post comments or reactions programmatically (<code>POST /api/comments</code> is a 404, <code>POST /api/reactions</code> is a 401 — I confirmed both a while back), so the pipeline drafts replies into a markdown file and I paste them by hand. Everything upstream of that manual step — <code>pending()</code> to find comments that need a draft, <code>audit()</code> to check whether a drafted reply actually made it onto the live thread — runs twice a day with nobody watching.</p> <p>Both of those functions sit on top of one helper, <code>api()</code>, in <code>reply_comments.py</code>:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight python"><code><span class="k">def</span> <span class="nf">api</span><span class="p">(</span><span class="n">path</span><span class="p">):</span> <span class="n">req</span> <span class="o">=</span> <span class="n">urllib</span><span class="p">.</span><span class="n">request</span><span class="p">.</span><span class="nc">Request</span><span class="p">(</span><span class="sh">"</span><span class="s">https://dev.to/api</span><span class="sh">"</span> <span class="o">+</span> <span class="n">path</span><span class="p">)</span> <span class="n">req</span><span class="p">.</span><span class="nf">add_header</span><span class="p">(</span><span class="sh">"</span><span class="s">api-key</span><span class="sh">"</span><span class="p">,</span> <span class="n">os</span><span class="p">.</span><span class="n">environ</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">DEV_TO_API</span><span class="sh">"</span><span class="p">,</span> <span class="sh">""</span><span class="p">))</span> <span class="n">req</span><span class="p">.</span><span class="nf">add_header</span><span class="p">(</span><span class="sh">"</span><span class="s">User-Agent</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Mozilla/5.0</span><span class="sh">"</span><span class="p">)</span> <span class="k">return</span> <span class="n">json</span><span class="p">.</span><span class="nf">load</span><span class="p">(</span><span class="n">urllib</span><span class="p">.</span><span class="n">request</span><span class="p">.</span><span class="nf">urlopen</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">30</span><span class="p">))</span> </code></pre> </div> <p>No <code>try</code>, no <code>except</code>. Just a request, a header, and <code>urlopen</code>.</p> <p>I found this while going back through the repo looking for anything that hadn't already been picked over — this file in particular has had three separate rounds of fixes, all in the tree-walking logic that decides <em>which</em> comment needs a reply: a recency bug in <code>needs_reply()</code>, a one-level-deep bug in <code>audit()</code>, a dedup key that pointed at the wrong node in <code>pending()</code>. Three fixes, three different functions, all downstream of <code>api()</code>. Nobody had ever looked at <code>api()</code> itself.</p> <p>And the reason that stung a little is that I'd already fixed this exact shape of bug once, in a completely different file. A few weeks back I found that <code>server.py</code> — the MCP server this repo also runs — had two HTTP helpers, <code>_gh()</code> for GitHub and <code>_dev()</code> for DEV.to, with the identical problem: no exception handling around <code>urlopen()</code>, so any <code>HTTPError</code> (a bad id, an expired token, a 429 rate limit) crashed straight through as a raw, unlabeled traceback. I fixed both, wrapping them so a bad call turns into a clean <code>RuntimeError</code> with the status code and response body instead of an opaque sta
分享
阅读原文