DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
腾讯云;让你的想法跑起来;轻量服务器 · 建站 / Docker / API;查看产品 →

Deno 的 setServername 已抛错,err.code 却是 undefined

Deno 旧 node:tls 兼容实现的 setServername 会抛普通错误,使 err.code 分支失效。核对 2.8.0 的参数类型与服务端 SNI 错误码修正。

Node 程序把 TLS 参数错误按 err.code 分类,换到 Deno 后,异常仍然被捕获,原来的错误分支却没有进入。若调用来自 node:tls 的 TLSSocket.setServername(),可以检查旧兼容实现是否只抛出了没有 code 的普通错误。

这项差异涉及两个明确条件:传入的服务器名不是字符串,以及在服务端 TLS socket 上调用客户端 SNI 设置。正式版 Deno 2.8.0 已包含相应的错误类型修正。

两种错误不能合并处理

非字符串名称应产生 TypeError,错误码为 ERR_INVALID_ARG_TYPE。这说明应用传错了值,需要回到配置解析或调用方修正,不能把它当成网络暂时不可达。

在服务端 socket 上调用 setServername(),应得到 ERR_TLS_SNI_FROM_SERVER。SNI 由客户端在握手中提供;服务端需要为不同名称选择证书时,要按服务端 TLS 配置处理,而不是在已建立的服务端 socket 上补发客户端 SNI。

旧 Deno 路径直接创建普通 TypeError 或 Error,所以错误文字看似正确,code 却不存在。业务若只匹配特定代码,可能落入兜底分支,甚至错误地继续使用没有完成预期设置的连接。

在已有调用点记录必要的错误分类即可,socket 与 servername 沿用应用自己的对象及配置:

try {
  socket.setServername(servername);
} catch (error) {
  console.error({
    name: error?.name,
    code: error?.code,
  });
  throw error;
}

这段保留失败,不会建立连接,也不会修正传错的名称。不要为获得一个预期错误码而在生产连接上故意传入数字,更不要打印包含连接凭据的整份配置。

更新兼容实现后复查调用契约

Deno 2.8.0 对两个条件改用 Node 兼容的带码错误类。更新实际运行服务的 Deno 后,在隔离环境分别检查这两条失败路径,确认类型和代码正确;再检查合法字符串在客户端连接中的原有行为。

错误码修正不表示错误条件变成合法操作。非字符串仍须修正,服务端调用仍须移到正确的 TLS 配置层。通过 String(value) 把任意值转换成主机名,也可能把错误配置变成另一个合法字符串,不应当作通用修复。

这不是证书信任或主机名校验的开关。不要关闭证书验证来消除 setServername 的参数错误;它不会补上缺失的错误代码,反而改变连接的认证边界。若更新后堆栈来自其他 API,应按那个 API 重新调查,不能靠匹配错误文字把所有 TLS 异常改成这两个代码。