<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>pal.world</title><description>读书、AI 与日常。</description><link>https://pal.world/</link><language>zh-CN</language><atom:link href="https://pal.world/rss.xml" rel="self" type="application/rss+xml"/><item><title>一个不存在的命令，让我的测试报了「0 失败」</title><link>https://pal.world/posts/false-green-from-a-missing-command/</link><guid isPermaLink="true">https://pal.world/posts/false-green-from-a-missing-command/</guid><description>macOS 上没有 timeout，于是整条验证管道 fail-open，给出了最令人安心的错误答案。</description><pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;提交前跑测试，想顺便确认失败数，写了这么一条：&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light-pal github-dark-pal&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;timeout&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt; 110&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt; python3&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt; -m&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt; pytest&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt; -q&lt;/span&gt;&lt;span style=&quot;color:#bf2f3c;--shiki-dark:#F97583&quot;&gt; 2&amp;gt;&amp;amp;1&lt;/span&gt;&lt;span style=&quot;color:#bf2f3c;--shiki-dark:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; grep&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt; -cE&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt; &apos;^(FAILED|ERROR)&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出：&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light-pal github-dark-pal&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;零失败，很好。差一点就提交了。&lt;/p&gt;
&lt;h2 id=&quot;但-macos-上没有-timeout&quot;&gt;但 macOS 上没有 timeout&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;timeout&lt;/code&gt; 是 GNU coreutils 的命令。macOS 自带的是 BSD 工具链，没有它
（装了 coreutils 也是叫 &lt;code&gt;gtimeout&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;所以实际发生的是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;timeout&lt;/code&gt; → &lt;code&gt;command not found&lt;/code&gt;，&lt;strong&gt;pytest 从来没有运行&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;管道左边没有任何输出&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grep -c&lt;/code&gt; 读到空输入，老老实实数出 &lt;strong&gt;0&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;我看到 0，以为是「0 个失败」&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;command not found&lt;/code&gt; 的报错确实打出来了，但它混在一堆输出里，而我的眼睛
直接跳到了最后那个数字。&lt;/p&gt;
&lt;h2 id=&quot;这个-bug-的恶劣之处&quot;&gt;这个 bug 的恶劣之处&lt;/h2&gt;
&lt;p&gt;它不是「验证失败了」，是&lt;strong&gt;验证坏掉的时候，给出了最令人安心的那个答案&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;一条用来抓错的管道，自己出故障时输出「没有错」。这是 fail-open 的教科书
案例，而且发生在最不该发生的地方——你专门写这条命令，就是为了在提交前
拦住问题。&lt;/p&gt;
&lt;p&gt;工具坏了输出「有问题」，你会去查。工具坏了输出「没问题」，你就直接提交了。&lt;/p&gt;
&lt;h2 id=&quot;怎么避免&quot;&gt;怎么避免&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;别把「没有匹配」和「没有输入」当成同一件事。&lt;/strong&gt; &lt;code&gt;grep -c&lt;/code&gt; 分不清这两者，
它只会数行。&lt;/p&gt;
&lt;p&gt;实际改法很简单——去掉 &lt;code&gt;timeout&lt;/code&gt;，直接看 pytest 自己的输出：&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light-pal github-dark-pal&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;160 passed in 0.13s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这一行同时告诉我两件事：跑了 160 个测试，以及&lt;strong&gt;它确实跑了&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;第二件事才是关键。任何一条「确认没问题」的命令，都得能证明它自己真的
执行过。数字是 0 不算证据，「160 passed」才算。&lt;/p&gt;
</content:encoded><category>踩坑</category><category>测试</category><category>shell</category></item><item><title>NameSilo 的 NS 列表：别把名字当成顺序</title><link>https://pal.world/posts/namesilo-nameservers-shape/</link><guid isPermaLink="true">https://pal.world/posts/namesilo-nameservers-shape/</guid><description>分清服务器名称、数组位置和 position 字段，以及为什么解析失败不能伪装成空结果。</description><pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;给自己的域名工具加「改 NS」命令，写解析的时候差点凭记忆猜返回形状。忍住了，
先打了一次真实 API 把响应打出来看——还好看了。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;2026-09-06 修订：原文的示例已经按 &lt;code&gt;position&lt;/code&gt; 排好，不能证明数组乱序；
「主从关系反了」的说法也不准确。下面保留原示例，并补上明确标注的测试输入。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;原文用来说明 &lt;code&gt;getDomainInfo&lt;/code&gt; 的 &lt;code&gt;nameservers&lt;/code&gt; 的片段是：&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light-pal github-dark-pal&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  { &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;&quot;nameserver&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;ns3.dnsowl.com&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;&quot;position&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  { &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;&quot;nameserver&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;ns2.dnsowl.com&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;&quot;position&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  { &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;&quot;nameserver&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;ns1.dnsowl.com&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;&quot;position&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里能看出来的是：&lt;strong&gt;数组第一个元素叫 &lt;code&gt;ns3&lt;/code&gt;，它的 &lt;code&gt;position&lt;/code&gt; 是 1。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;名字里的 &lt;code&gt;3&lt;/code&gt; 不等于数组里的第三项，也不能据此判断 DNS 的主从关系。
这段数组的 &lt;code&gt;position&lt;/code&gt; 恰好就是 1、2、3，直接遍历和按 &lt;code&gt;position&lt;/code&gt; 排序，
得到的都是 &lt;code&gt;ns3, ns2, ns1&lt;/code&gt;。原文说它「顺序完全对不上」，是把两件事混在了一起。&lt;/p&gt;
&lt;p&gt;DNS 的主从区别与区域数据的来源有关，不能从 NS 名称的数字后缀推断；
对于外部解析器，它们都是提供该区域答案的服务器。
这点可参见 &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc2182.html#section-3&quot;&gt;RFC 2182 第 2、3 节&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;为什么这个错误特别难发现&quot;&gt;为什么这个错误特别难发现&lt;/h2&gt;
&lt;p&gt;难发现的是比较逻辑里的假设。单看「读 NS」，读到了三个名字，看起来就像成功了。&lt;/p&gt;
&lt;p&gt;这个假设一旦进入&lt;strong&gt;回读验证&lt;/strong&gt;，就会影响成败判断。改 NS 这种操作，我的规矩是
「成功以回读为准」：调完写接口，再读一次，比对是不是目标值。可要是验证逻辑
把列表顺序也算进相等条件，只是换了排列，就可能报「改失败了」——即使服务器
集合已经符合目标。&lt;/p&gt;
&lt;p&gt;所以先说明白自己在验证什么。如果只是确认域名使用了哪几台 NS，就应该在
校验名称、统一大小写和末尾点之后比较集合。注册商 API 的回读也只说明其记录状态，
不能单凭这一项断言公网 DNS 已经全部更新。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一个用来判断成败的函数自己是错的，比功能本身有 bug 危险得多。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果工具另有需求，要按 &lt;code&gt;position&lt;/code&gt; 展示条目，则应明确使用这个字段。
下面是专门构造的乱序测试输入，&lt;strong&gt;不是一次真实 API 响应&lt;/strong&gt;：&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light-pal github-dark-pal&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;raw &lt;/span&gt;&lt;span style=&quot;color:#bf2f3c;--shiki-dark:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;nameserver&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;ns1.example.com&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;position&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;nameserver&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;ns3.example.com&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;position&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;nameserver&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;ns2.example.com&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;position&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;字段通过解析层校验后，排序这一步可以写成：&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light-pal github-dark-pal&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;ordered &lt;/span&gt;&lt;span style=&quot;color:#bf2f3c;--shiki-dark:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt; tuple&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    item[&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;nameserver&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#bf2f3c;--shiki-dark:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; item &lt;/span&gt;&lt;span style=&quot;color:#bf2f3c;--shiki-dark:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt; sorted&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(raw, &lt;/span&gt;&lt;span style=&quot;color:#a64f00;--shiki-dark:#FFAB70&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color:#bf2f3c;--shiki-dark:#F97583&quot;&gt;=lambda&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; item: item[&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;position&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#50677a;--shiki-dark:#9fb9ca&quot;&gt;# (&quot;ns3.example.com&quot;, &quot;ns2.example.com&quot;, &quot;ns1.example.com&quot;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它验证的是「是否按字段排序」。真实接口接受哪些形状、是否保证数组顺序，
仍要结合接口文档和保存的响应核对，不能从这个测试输入反推。&lt;/p&gt;
&lt;h2 id=&quot;顺带一条解析不出来的时候别返回空&quot;&gt;顺带一条：解析不出来的时候别返回空&lt;/h2&gt;
&lt;p&gt;同一个函数里还有个更隐蔽的决定：形状不认识时该怎么办。&lt;/p&gt;
&lt;p&gt;返回空元组是最省事的写法，也是最危险的。因为回读验证的逻辑是
「读出来的 == 想要的？」，期望非空时，读到空就会误报不一致；如果期望值也
意外变成空，还可能误报成功。于是，&lt;strong&gt;没生效和读不懂，被压成了同一个结果&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;而这一步正是判断成败的唯一依据。所以解析不出来就抛错：&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light-pal github-dark-pal&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#bf2f3c;--shiki-dark:#F97583&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; NameSiloError(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;解析不了 &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;%s&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt; 的 nameservers 段:&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;%.100r&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#bf2f3c;--shiki-dark:#F97583&quot;&gt; %&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; (where, raw))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;宁可整条命令红着停下，也不要给出一个看起来能用、实则失去意义的答案。&lt;/p&gt;
&lt;h2 id=&quot;真正的教训&quot;&gt;真正的教训&lt;/h2&gt;
&lt;p&gt;不是「NameSilo 的 API 设计得怪」——第三方 API 本来就会怪。&lt;/p&gt;
&lt;p&gt;是&lt;strong&gt;别凭记忆猜响应形状&lt;/strong&gt;。猜错的代价不是报错，是一个安静跑着、结论全错的
解析器。打一次真实请求，把返回打印出来，成本三十秒。&lt;/p&gt;
</content:encoded><category>踩坑</category><category>API</category><category>域名</category></item></channel></rss>