[box class="blue_box" title="☑本記事の内容"]
- log
- エラーハンドリング
- panicとrecover
[/box]
参考資料:現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発
[box class="glay_box" title="Contents"]
[/box]
log
[box class="yellow_box" title="✔logの目次"]
[/box]
基本的なこと
[box class="glay_box"]
- 公式サイトで標準ライブラリの確認が出来る
- 他のプログラミングと言語違い標準ライブラリにはlogを出すパッケージが最低限のものしかない
- サードパーティのライブラリを使うと他の言語と似たようなものもある
[/box]
package main
import "log"
func main() {
log.Println("logging!")
log.Printf("%T %v", "test", "test")
}
(結果)
2021/02/02 21:04:35 logging!
2021/02/02 21:04:35 string test
errorlog
[box class="glay_box"]
- Fatalを使う事でerrorlogを出せる
- Fatalを使うとその後の処理は起こらない
[/box]
package main
import (
"fmt"
"log"
)
func main() {
log.Fatalf("%T %v", "test", "test")
fmt.Println("ok?")
}
(結果)
2021/02/02 21:06:25 string test
Process exiting with code: 1 signal: false
logファイルの出力
[box class="glay_box"]
- 標準ライブラリでもlogファイルの出力が出来る
- 最低限のものなので、詳しいlogファイルを出力したいときはサードパーティのライブラリを使用
- 下記のコードではtest.logが出力される
[/box]
func LoggingSettings(logFile string) {
logfile, _ := os.OpenFile(logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
multiLogFile := io.MultiWriter(os.Stdout, logfile)
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.SetOutput(multiLogFile)
}
func main() {
LoggingSettings("test.log")
_, err := os.Open("fdafdsafa")
if err != nil {
log.Fatalln("Exit", err)
}
}
(結果)
2021/02/02 21:13:40 lesson.go:20: Exit open fdafdsafa: The system cannot find the file specified.
Process exiting with code: 1 signal: false
(ファイルの中身)
2021/02/02 21:13:40 lesson.go:20: Exit open fdafdsafa: The system cannot find the file specified.
エラーハンドリング
[box class="yellow_box" title="✔エラーハンドリングの目次"]
[/box]
基本的なこと
[box class="glay_box"]
- file, errのように後ろにエラーの変数を加える
- errが空でない場合は処理をlogを出力するようにする
- エラーの場合はerrにstringが入ってくる
[/box]
package main
import (
"fmt"
"log"
"os"
)
func main() {
file, err := os.Open("./lesson.go")
if err != nil {
log.Fatalln("Error!")
}
defer file.Close()
data := make([]byte, 20)
count, err := file.Read(data)
if err != nil {
log.Fatalln("Error")
}
fmt.Println(count, string(data))
}
(結果)
20 package main
impo
補足
[box class="glay_box"]
- file, err :=とcount,err
:=とerrを2回イニシャライズしているがこれは大丈夫 - 片方だけでも初めて変数宣言している場合はエラーにならない
- errのみ再度変数宣言をするとエラーになる
[/box]
package main
import (
"log"
"os"
)
func main() {
file, err := os.Open("./lesson.go")
if err != nil {
log.Fatalln("Error!")
}
defer file.Close()
err := os.Chdir("test")
}
(結果)エラー表示
no new variables on left side of :=
panicとrecover
[box class="yellow_box" title="✔panicとrecoverの目次"]
[/box]
panic
[box class="glay_box"]
- 例外処理を追加すること
- panicが起きると処理が強制終了する
[/box]
package main
import "fmt"
func thirdPartyConnectDB() {
panic("Unable to connect database!")
}
func save() {
thirdPartyConnectDB()
}
func main() {
save()
fmt.Println("OK?")
}
(結果)
panic: Unable to connect database!
goroutine 1 [running]:
recover
[box class="glay_box"]
- panicから復帰させること
- recoverよりもpanicが先にあると復帰出来ない
[/box]
package main
import "fmt"
func thirdPartyConnectDB() {
panic("Unable to connect database!")
}
func save() {
defer func() {
s := recover()
fmt.Println(s)
}()
thirdPartyConnectDB()
}
func main() {
save()
fmt.Println("OK?")
}
(結果)
Unable to connect database!
OK?
注意点
[box class="glay_box"]
- Goではpanicを使用することを推奨していない
- panicはエラー原因が分からずに起きていること
- エラーハンドリングでしっかりとエラー状況を把握するのが大事
[/box]