2024-01-29
概要
- Go言語でコマンドラインツールを作るとき cobra というライブラリが便利
- cobra では通常 Command.Run というフィールドにハンドラ (関数) をセットする
- Command.Run のハンドラではエラーを返せない
- Command.RunE というフィールドもあり、このハンドラではエラーを返せる
エラーが起きたら log.Fatal するしかない? という課題感
Command.Run のハンドラのシグネチャは func(cmd *Command, args []string)
です。
Go言語あるあるな「エラーを返す」ということができません。
そのためエラーが起きたら log.Fatal
して終わらせていたのですが、テストをしづらく課題に感じてました。
package main import ( "log" "github.com/spf13/cobra" ) func main() { cli := &cobra.Command{ Use: "samplecli", Version: "0.0.1", // エラーを返せない Run: func(cmd *cobra.Command, args []string) { if err := processData(); err != nil { log.Fatalf("Error: %s", err.Error()) } }, } cli.Execute() }
ところが cobra には Command.RunE というフィールドもあり、ここではエラーを返せることを知りました。
Command.RunE ではエラーを返せる
Command.RunE のハンドラのシグネチャは func(cmd *Command, args []string) error
です。
エラーを返せます。
package main import ( "os" "github.com/spf13/cobra" ) func main() { cli := &cobra.Command{ Use: "samplecli", Version: "0.0.1", // エラーを返せる RunE: func(cmd *cobra.Command, args []string) error { if err := processData(); err != nil { return err } return nil }, } if err := cli.Execute(); err != nil { os.Exit(1) } }
エラーメッセージを出力してくれる
Command.RunE のハンドラでエラーを返すと cobra がエラーメッセージを出力します。
$ samplecli Error: failed to process data
この挙動は SilenceErrors
で無効にできます。
cli.SilenceErrors = true
感想
正直好みの問題ですが私はエラーを返す方が自然に思え好きです。
テストをしやすくなりますし、エラーのたびに log.Fatal() を書くのも面倒かと思い。。
作成日
2024-01-29
更新日
2024-02-03