Golang errcheck による defer 警告対応

概要

このようなコードを書いていると errcheck を実行した場合、 defer f.Close() と指摘されてしまいます。

1
2
3
4
5
6
7
8
9
10
func hoge() error {
...
f, err := os.Open(fpath)
if err != nil {
return err
}

defer f.Close()
...
}

f.Close() は返り値が error であり、その error の返り値をチェックしていない、という警告です。

対応

その為、以下のように修正することで回避

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func hoge() error {
...
f, err := os.Open(fpath)
if err != nil {
return err
}

defer func() {
err = f.Close()
if err != nil {
log.Fatalln(err)
}
}()
...
}

但し、上記の場合だと error 発生した時に panic が発生します。

log.Println すると error がログ出力こそされますが、その error によって後続の処理をハンドリングすることができません。

その為、さらに以下の様に修正してみました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func hoge() (err error) {
...
f, err := os.Open(filepath.Clean(fpath))
if err != nil {
return err
}

defer func() {
if er := f.Close(); er != nil {
err = er
}
}()
...
}

以下対応手順で f.Close()errorhoge() の戻り値として返すことができます。

  • hoge() 関数の戻り値で err error と変数名を指定する
  • defer している func(){} 内で f.Close() の戻り値 errorerr に格納する

Go Playground

参考

随分前に既に掲題について話をしていた

ignore defer calls #55

Author

Kenzo Tanaka

Posted on

2019-12-09

Licensed under

コメント