Daily Tech Briefing
AI 科技速览
每天 5 分钟内学习 AI。获取最新的人工智能新闻,理解其重要性,并学习如何将其应用于您的工作。
Dev.to AI · 2026/8/2 12:37:38
My Comment-Reply Queue Draft One Reply to a Thread and It Went Deaf to Every Follow-Up After That
AI 中文解读
这位开发者的评论管理小工具连续踩了三个坑,而且第三个坑藏得很深,恰恰是因为前两个修得太干净,让人放松了警惕。他写的脚本用来追踪DEV.to文章下面的新评论,先是修复了回复一次后整个对话就被标记为处理完毕、对方再追问也不提醒的bug,又修了只检查第一层回复而漏掉深层嵌套评论的问题。结果今天发现核心判断逻辑里还藏着第三个问题,而且这个bug因为前面两个修复让整份代码看起来太可信,反而更不容易被察觉。
这其实反映了编程中常见的困境:一个工具用久了,慢慢积累的小补丁会让你以为它已经很可靠,结果最隐蔽的漏洞恰恰藏在你最放心的角落。虽然这个脚本只是开发者个人的效率工具,但这种教训对任何人都有启发——无论是管理邮件、处理工作流程还是做日常记录,定期用批判眼光重新审视自己用惯了的工具,往往能发现被忽视的盲区。
<p>I have a small script, <code>reply_comments.py</code>, that keeps me from having to re-scan every DEV.to article for new comments by hand. It has two commands: <code>pending</code> (unanswered comments I haven't drafted a reply to yet) and <code>audit</code> (drafted replies I said I'd paste manually but apparently never did). I've already fixed two bugs in this file — one in <code>needs_reply()</code> (a thread stayed "handled" forever after a single reply, even when the other person followed up again) and one in <code>audit()</code> (it only checked direct children, so a reply nested two levels deep was invisible). Today I found a third, in <code>pending()</code> itself, and it's the kind of bug that hides precisely because the first two fixes made everything else in the file look trustworthy.</p>
<h2>
What <code>pending()</code> actually does
</h2>
<p>Comments on DEV.to come back from the API as trees — each top-level comment has a <code>children</code> list, and replies can nest arbitrarily deep. <code>pending()</code> walks each article's top-level comments and decides, for each one, whether it needs a reply:<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="k">def</span> <span class="nf">pending</span><span class="p">():</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">drafted_text</span> <span class="o">=</span> <span class="nf">open</span><span class="p">(</span><span class="n">DRAFTS</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="sh">"</span><span class="s">utf-8</span><span class="sh">"</span><span class="p">).</span><span class="nf">read</span><span class="p">()</span>
<span class="k">except</span> <span class="nb">FileNotFoundError</span><span class="p">:</span>
<span class="n">drafted_text</span> <span class="o">=</span> <span class="sh">""</span>
<span class="n">drafted_codes</span> <span class="o">=</span> <span class="nf">set</span><span class="p">(</span><span class="n">re</span><span class="p">.</span><span class="nf">findall</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">^## (\S+)</span><span class="sh">"</span><span class="p">,</span> <span class="n">drafted_text</span><span class="p">,</span> <span class="n">re</span><span class="p">.</span><span class="n">M</span><span class="p">))</span>
<span class="n">out</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="nf">api</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">/articles?username=</span><span class="si">{</span><span class="n">ME</span><span class="si">}</span><span class="s">&per_page=100</span><span class="sh">"</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">a</span><span class="p">[</span><span class="sh">"</span><span class="s">comments_count</span><span class="sh">"</span><span class="p">]:</span>
<span class="k">continue</span>
<span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="nf">api</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">/comments?a_id=</span><span class="si">{</span><span class="n">a</span><span class="p">[</span><span class="sh">'</span><span class="s">id</span><span class="sh">'</span><span class="p">]</span><span class="si">}</span><span class="sh">"</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nf">needs_reply</span><span class="p">(</span><span class="n">c</span><span class="p">):</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">c</span><span class="p">[</span><span cl
分享
阅读原文 ↗