🛹今goのエラーハンドリングを無難にしておく方法(2021.09現在)2021/07/11に公開2022/06/128件GoerrortechDiscussionSpiegel2021/07/14標準 errors パッケージでもエラーのラッピングは既に実装されていますよ。 erros.Unwrap(), errors.Is(), errors.As() 関数でハンドリングします。また fmt.Errorf() 関数で %w 書式を使ってラップすることが可能です。 Go 2 に絡めるなら Generics 導入で errors.As() 関数のバリエーションが増える可能性はありますが,今のところは Go 2 も含めて現状が最終形です。 ただし標準パケージではスタックトレースは実装されていないので,この情報が必要なら自前で型を用意するか pkg/errors パッケージを使う,という住み分けになるんだと思います。 pkg/errors パッケージは放置されているわけではなく,設計がシンプルでバグが出る余地が少ないので改修頻度が少ないだけで,あちこちで使われてますよ。 pkg/errors の errors.(*withStack).Cause() 関数は(コードを見れば分かりますが) errors.(*withStack).Unwrap() 関数と同一のコードです。むしろ errors.(*withStack).Cause() 関数は自パッケージの後方互換性確保のために残されてると言った方がいいでしょうか。これから使うのであれば標準の erros.Unwrap(), errors.Is(), errors.As() 関数と組み合わせてハンドリングするのがいいと思います。 Nekoshita Yuki2021/07/14に更新ご指摘いただきありがとうございます! 標準 errors パッケージでもエラーのラッピングは既に実装されていますよ。 その通りですmm 最後の項目ではerrorのラップの話ではなくstacktraceの話をしているつもりでした なので、最後の項目を以下のように変更しました。 結局標準errorsはラップする機能は取り込まれないの? -> 結局標準errorsにstacktraceの機能は取り込まれないの? Nekoshita Yuki2021/07/14 標準パケージではスタックトレースは実装されていないので,この情報が必要なら自前で型を用意するか pkg/errors パッケージを使う,という住み分けになるんだと思います 僕も同じ認識です! pkg/errors パッケージは放置されているわけではなく,設計がシンプルでバグが出る余地が少ないので改修頻度が少ないだけで,あちこちで使われてますよ。 そうですね、僕の表現の仕方が放置してるっぽくなってしまっていたので修正しました Nekoshita Yuki2021/07/14 pkg/errors の errors.(*withStack).Cause() 関数は(コードを見れば分かりますが) errors.(*withStack).Unwrap() 関数と同一のコードです。むしろ errors.(*withStack).Cause() 関数は自パッケージの後方互換性確保のために残されてると言った方がいいでしょうか。これから使うのであれば標準の erros.Unwrap(), errors.Is(), errors.As() 関数と組み合わせてハンドリングするのがいいと思います。 pkg/errors.Casue()とpkg/errors.Unwrap() のコードは異なるようにみえます。 pkg/errorsを使ってエラーを発生させた場合のエラー原因の特定のために、pkg/errors.Cause()、pkg/errors.Is()、標準errors.Is()のどれを使っても問題なくハンドリングできるので、そこは好みで使い分けて良いと思います! 1点注意が必要なのが、pkg/errorsを使って発生させたエラーを pkg/errors.Unwrap()か標準errors/Unwrap() する際の場合の挙動についてです。 https://github.com/pkg/errors/issues/223#issuecomment-587372942 詳細はこちらになりますが、pkg/errorsを使って発生させたエラーを2回 Unwrap()しないと1回分のUnwrapができません。 なので、pkg/errorsを使って発生させたエラーの原因を特定する場合には、 pkg/errors.Cause()、pkg/errors.Is()、標準errors.Is() を使うのがよさそうです。 Spiegel2021/07/14おー,なるほど。情報をありがとうございます。 pkg/errors の errors.Cause() と errors.(*withStack).Cause() および errors.Unwrap() と errors.(*withStack).Unwrap() がごっちゃの説明になってましたね。すみません。 返信を追加yu2022/05/09https://github.com/pkg/errors/issues/245 Quite clearly this package has been unmaintained for a long time. 返信を追加tenntenn2022/06/09プロポーザルを読み直しましたが、スタックトレースについてGo2でリリースされるとは書いてなさそうです。 そもそも、Go2というのは、後方互換が崩れるような変更を入れざる得ない時に生まれるバージョンなので、今の所予定はないと思います。 スタックトレースはGo1.13の開発時にxerrorsから輸入され、その後リリース前に消されたという経緯があります。 https://github.com/golang/go/issues/30468 https://go-review.googlesource.com/c/go/+/176997 Nekoshita Yuki2022/06/12ご指摘、詳細な経緯をいただきありがとうございます!本文を修正させていただきました🙏 返信を追加
Spiegel2021/07/14標準 errors パッケージでもエラーのラッピングは既に実装されていますよ。 erros.Unwrap(), errors.Is(), errors.As() 関数でハンドリングします。また fmt.Errorf() 関数で %w 書式を使ってラップすることが可能です。 Go 2 に絡めるなら Generics 導入で errors.As() 関数のバリエーションが増える可能性はありますが,今のところは Go 2 も含めて現状が最終形です。 ただし標準パケージではスタックトレースは実装されていないので,この情報が必要なら自前で型を用意するか pkg/errors パッケージを使う,という住み分けになるんだと思います。 pkg/errors パッケージは放置されているわけではなく,設計がシンプルでバグが出る余地が少ないので改修頻度が少ないだけで,あちこちで使われてますよ。 pkg/errors の errors.(*withStack).Cause() 関数は(コードを見れば分かりますが) errors.(*withStack).Unwrap() 関数と同一のコードです。むしろ errors.(*withStack).Cause() 関数は自パッケージの後方互換性確保のために残されてると言った方がいいでしょうか。これから使うのであれば標準の erros.Unwrap(), errors.Is(), errors.As() 関数と組み合わせてハンドリングするのがいいと思います。 Nekoshita Yuki2021/07/14に更新ご指摘いただきありがとうございます! 標準 errors パッケージでもエラーのラッピングは既に実装されていますよ。 その通りですmm 最後の項目ではerrorのラップの話ではなくstacktraceの話をしているつもりでした なので、最後の項目を以下のように変更しました。 結局標準errorsはラップする機能は取り込まれないの? -> 結局標準errorsにstacktraceの機能は取り込まれないの? Nekoshita Yuki2021/07/14 標準パケージではスタックトレースは実装されていないので,この情報が必要なら自前で型を用意するか pkg/errors パッケージを使う,という住み分けになるんだと思います 僕も同じ認識です! pkg/errors パッケージは放置されているわけではなく,設計がシンプルでバグが出る余地が少ないので改修頻度が少ないだけで,あちこちで使われてますよ。 そうですね、僕の表現の仕方が放置してるっぽくなってしまっていたので修正しました Nekoshita Yuki2021/07/14 pkg/errors の errors.(*withStack).Cause() 関数は(コードを見れば分かりますが) errors.(*withStack).Unwrap() 関数と同一のコードです。むしろ errors.(*withStack).Cause() 関数は自パッケージの後方互換性確保のために残されてると言った方がいいでしょうか。これから使うのであれば標準の erros.Unwrap(), errors.Is(), errors.As() 関数と組み合わせてハンドリングするのがいいと思います。 pkg/errors.Casue()とpkg/errors.Unwrap() のコードは異なるようにみえます。 pkg/errorsを使ってエラーを発生させた場合のエラー原因の特定のために、pkg/errors.Cause()、pkg/errors.Is()、標準errors.Is()のどれを使っても問題なくハンドリングできるので、そこは好みで使い分けて良いと思います! 1点注意が必要なのが、pkg/errorsを使って発生させたエラーを pkg/errors.Unwrap()か標準errors/Unwrap() する際の場合の挙動についてです。 https://github.com/pkg/errors/issues/223#issuecomment-587372942 詳細はこちらになりますが、pkg/errorsを使って発生させたエラーを2回 Unwrap()しないと1回分のUnwrapができません。 なので、pkg/errorsを使って発生させたエラーの原因を特定する場合には、 pkg/errors.Cause()、pkg/errors.Is()、標準errors.Is() を使うのがよさそうです。 Spiegel2021/07/14おー,なるほど。情報をありがとうございます。 pkg/errors の errors.Cause() と errors.(*withStack).Cause() および errors.Unwrap() と errors.(*withStack).Unwrap() がごっちゃの説明になってましたね。すみません。 返信を追加
Nekoshita Yuki2021/07/14に更新ご指摘いただきありがとうございます! 標準 errors パッケージでもエラーのラッピングは既に実装されていますよ。 その通りですmm 最後の項目ではerrorのラップの話ではなくstacktraceの話をしているつもりでした なので、最後の項目を以下のように変更しました。 結局標準errorsはラップする機能は取り込まれないの? -> 結局標準errorsにstacktraceの機能は取り込まれないの?
Nekoshita Yuki2021/07/14 標準パケージではスタックトレースは実装されていないので,この情報が必要なら自前で型を用意するか pkg/errors パッケージを使う,という住み分けになるんだと思います 僕も同じ認識です! pkg/errors パッケージは放置されているわけではなく,設計がシンプルでバグが出る余地が少ないので改修頻度が少ないだけで,あちこちで使われてますよ。 そうですね、僕の表現の仕方が放置してるっぽくなってしまっていたので修正しました
Nekoshita Yuki2021/07/14 pkg/errors の errors.(*withStack).Cause() 関数は(コードを見れば分かりますが) errors.(*withStack).Unwrap() 関数と同一のコードです。むしろ errors.(*withStack).Cause() 関数は自パッケージの後方互換性確保のために残されてると言った方がいいでしょうか。これから使うのであれば標準の erros.Unwrap(), errors.Is(), errors.As() 関数と組み合わせてハンドリングするのがいいと思います。 pkg/errors.Casue()とpkg/errors.Unwrap() のコードは異なるようにみえます。 pkg/errorsを使ってエラーを発生させた場合のエラー原因の特定のために、pkg/errors.Cause()、pkg/errors.Is()、標準errors.Is()のどれを使っても問題なくハンドリングできるので、そこは好みで使い分けて良いと思います! 1点注意が必要なのが、pkg/errorsを使って発生させたエラーを pkg/errors.Unwrap()か標準errors/Unwrap() する際の場合の挙動についてです。 https://github.com/pkg/errors/issues/223#issuecomment-587372942 詳細はこちらになりますが、pkg/errorsを使って発生させたエラーを2回 Unwrap()しないと1回分のUnwrapができません。 なので、pkg/errorsを使って発生させたエラーの原因を特定する場合には、 pkg/errors.Cause()、pkg/errors.Is()、標準errors.Is() を使うのがよさそうです。
Spiegel2021/07/14おー,なるほど。情報をありがとうございます。 pkg/errors の errors.Cause() と errors.(*withStack).Cause() および errors.Unwrap() と errors.(*withStack).Unwrap() がごっちゃの説明になってましたね。すみません。
yu2022/05/09https://github.com/pkg/errors/issues/245 Quite clearly this package has been unmaintained for a long time. 返信を追加
tenntenn2022/06/09プロポーザルを読み直しましたが、スタックトレースについてGo2でリリースされるとは書いてなさそうです。 そもそも、Go2というのは、後方互換が崩れるような変更を入れざる得ない時に生まれるバージョンなので、今の所予定はないと思います。 スタックトレースはGo1.13の開発時にxerrorsから輸入され、その後リリース前に消されたという経緯があります。 https://github.com/golang/go/issues/30468 https://go-review.googlesource.com/c/go/+/176997 Nekoshita Yuki2022/06/12ご指摘、詳細な経緯をいただきありがとうございます!本文を修正させていただきました🙏 返信を追加
Discussion
標準 errors パッケージでもエラーのラッピングは既に実装されていますよ。 erros.Unwrap(), errors.Is(), errors.As() 関数でハンドリングします。また fmt.Errorf() 関数で %w 書式を使ってラップすることが可能です。 Go 2 に絡めるなら Generics 導入で errors.As() 関数のバリエーションが増える可能性はありますが,今のところは Go 2 も含めて現状が最終形です。
ただし標準パケージではスタックトレースは実装されていないので,この情報が必要なら自前で型を用意するか pkg/errors パッケージを使う,という住み分けになるんだと思います。 pkg/errors パッケージは放置されているわけではなく,設計がシンプルでバグが出る余地が少ないので改修頻度が少ないだけで,あちこちで使われてますよ。
pkg/errors の errors.(*withStack).Cause() 関数は(コードを見れば分かりますが) errors.(*withStack).Unwrap() 関数と同一のコードです。むしろ errors.(*withStack).Cause() 関数は自パッケージの後方互換性確保のために残されてると言った方がいいでしょうか。これから使うのであれば標準の erros.Unwrap(), errors.Is(), errors.As() 関数と組み合わせてハンドリングするのがいいと思います。
ご指摘いただきありがとうございます!
その通りですmm
最後の項目ではerrorのラップの話ではなくstacktraceの話をしているつもりでした
なので、最後の項目を以下のように変更しました。
結局標準errorsはラップする機能は取り込まれないの?-> 結局標準errorsにstacktraceの機能は取り込まれないの?
僕も同じ認識です!
そうですね、僕の表現の仕方が放置してるっぽくなってしまっていたので修正しました
pkg/errors.Casue()とpkg/errors.Unwrap() のコードは異なるようにみえます。
pkg/errorsを使ってエラーを発生させた場合のエラー原因の特定のために、pkg/errors.Cause()、pkg/errors.Is()、標準errors.Is()のどれを使っても問題なくハンドリングできるので、そこは好みで使い分けて良いと思います!1点注意が必要なのが、
pkg/errorsを使って発生させたエラーをpkg/errors.Unwrap()か標準errors/Unwrap()する際の場合の挙動についてです。詳細はこちらになりますが、
pkg/errorsを使って発生させたエラーを2回Unwrap()しないと1回分のUnwrapができません。なので、
pkg/errorsを使って発生させたエラーの原因を特定する場合には、pkg/errors.Cause()、pkg/errors.Is()、標準errors.Is()を使うのがよさそうです。おー,なるほど。情報をありがとうございます。
pkg/errors の errors.Cause() と errors.(*withStack).Cause() および errors.Unwrap() と errors.(*withStack).Unwrap() がごっちゃの説明になってましたね。すみません。
プロポーザルを読み直しましたが、スタックトレースについてGo2でリリースされるとは書いてなさそうです。
そもそも、Go2というのは、後方互換が崩れるような変更を入れざる得ない時に生まれるバージョンなので、今の所予定はないと思います。
スタックトレースはGo1.13の開発時にxerrorsから輸入され、その後リリース前に消されたという経緯があります。
ご指摘、詳細な経緯をいただきありがとうございます!本文を修正させていただきました🙏