net: deprecate DNSConfigError
要約
概要
net パッケージの DNSConfigError 型を、Go の正式な非推奨(Deprecated)コメントで非推奨にする提案です。この型は2015年以降標準ライブラリ内で一度も返されていませんが、ドキュメント上は「使われていない」と書かれているだけで、正式な非推奨扱いになっていませんでした。
ステータス変更
(新規) → likely_accept
2023年9月に Mateusz Poliwczak 氏(@mateusz834)が起票し、約3年後の2026年10月1日、proposal review group を代表して @aclements 氏が「likely accept」と判断しました。issue 上で議論はほとんどなく、反対意見も出ていません。この型が実際に使われていないことはソースコードとドキュメントの両方からはっきりしており、非推奨化しても既存コードは壊れないため、異論の余地が少ない提案として扱われたと考えられます。承認まで時間がかかったのは議論が割れたからではなく、優先度の低い整理的な提案として審査の順番待ちが長かったためと思われます。
技術的背景
現状の問題点
DNSConfigError は現在、次のように定義されています。
// DNSConfigError represents an error reading the machine's DNS configuration.
// (No longer used; kept for compatibility.)
type DNSConfigError struct {
Err error
}
func (e *DNSConfigError) Unwrap() error { return e.Err }
func (e *DNSConfigError) Error() string { return "error reading DNS config: " + e.Err.Error() }
func (e *DNSConfigError) Timeout() bool { return false }
func (e *DNSConfigError) Temporary() bool { return false }
この型は元々、/etc/resolv.conf の読み込み失敗を表すエラーでした。2015年の CL 9380(#10566 の修正)で、resolv.conf が存在しない・読めない・nameserver の記載がない場合は、man page の仕様どおりローカルホストの DNS サーバーを使うように変わりました。それ以降、このエラーは返されなくなっています。
ただしコメントは「(No longer used; kept for compatibility.)」という書き方で、Go の慣例である // Deprecated: 形式になっていません。そのため次のような問題がありました。
staticcheck(SA1019)やgoplsなどのツールが警告を出さない- pkg.go.dev で非推奨として折りたたみ表示されず、現役の API に見える
errors.As(err, &dnsConfigErr)のように、絶対に一致しないエラー判定を書いてしまう可能性がある
提案された解決策
既存のコメントを Go 標準の非推奨表記に置き換えます。後方互換性(Go 1 互換性保証)のため、型とメソッド自体は削除しません。具体的な文言は実装 CL で決まりますが、たとえば次のような形が想定されます。
// DNSConfigError represents an error reading the machine's DNS configuration.
//
// Deprecated: No longer used; kept for compatibility.
type DNSConfigError struct { ... }
これによって何ができるようになるか
- 静的解析での検出:
staticcheckやgoplsがDNSConfigErrorの使用箇所を警告するので、意味のないエラー判定コードを見つけて削除しやすくなります。 - ドキュメントの分かりやすさ: pkg.go.dev で非推奨 API として区別して表示され、
netパッケージのエラー型を調べる開発者が迷わなくなります。 - 正しいエラー処理への誘導: DNS 関連のエラーは
*net.DNSErrorで扱うべきだと分かりやすくなります。
コード例
// Before: 一致することのないエラー判定(ツールは何も警告しない)
addrs, err := net.LookupHost("example.com")
if err != nil {
var cfgErr *net.DNSConfigError
if errors.As(err, &cfgErr) { // Go 1.5 以降、ここに来ることはない
log.Printf("DNS 設定の読み込み失敗: %v", cfgErr.Err)
}
}
// After: 非推奨化により staticcheck 等が警告するので、DNSError で判定する
addrs, err := net.LookupHost("example.com")
if err != nil {
var dnsErr *net.DNSError
if errors.As(err, &dnsErr) {
log.Printf("DNS 解決失敗: name=%s notFound=%v timeout=%v",
dnsErr.Name, dnsErr.IsNotFound, dnsErr.IsTimeout)
}
}
議論のハイライト
- 提案者は「CL 9380 以降は使われておらず、ドキュメントにもそう書いてあるのに、なぜ正式に非推奨にしないのか」と問いかけました。提案の中身はこの問いだけです。
- 変更はコメントの修正だけで、型やメソッドは残します。Go 1 互換性保証により公開 API は削除できないため、
// Deprecated:を付けることがとれる最大の措置です。 - issue 上で反対意見や代わりの案は出ていません。2023年の起票から約3年後に、review group がそのまま likely accept と判断しました。
- 結論が変わらなければ、Final Comment Period(最終コメント期間。
Proposal-FinalCommentPeriodラベル付き)を経て正式に accept されます。