いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-212 (log.Fatalとlog.Panicの違い)

概要

何気に違いをちゃんと知らなかったので、忘れないうちにメモメモ。。。

  • log.Panicの方はpanicが呼ばれるので defer が処理される
  • log.Fatalの方はdeferが処理されない
  • log.Fatalの方はOSへ戻り値が 1 で返却される (linuxの場合)
  • log.Panicの方はOSへ戻り値が 2 で返却される (linuxの場合)

サンプル

log.Fatal

package main

import (
    "log"
    "os"
)

var (
    l = log.New(os.Stderr, ">>> ", 0)
)

func main() {
    // log.Fatal は、os.Exit(1) を呼び出すのでdeferが呼ばれない
    // log.Fatal は、OSに戻り値 1 を返す (linuxの場合)
    //
    // REFERENCES:
    //   - https://zenn.dev/spiegel/books/error-handling-in-golang/viewer/panics
    defer l.Println("call defer")
    l.Fatalln("call log.Fatal")
}

log.Panic

package main

import (
    "log"
    "os"
)

var (
    l = log.New(os.Stderr, ">>> ", 0)
)

func main() {
    // log.Panic は、panicを呼び出すのでdeferが呼ばれる
    // log.Panic は、OSに戻り値 2 を返す (linuxの場合)
    //
    // REFERENCES:
    //   - https://zenn.dev/spiegel/books/error-handling-in-golang/viewer/panics
    defer l.Println("call defer")
    l.Panicln("call log.Panic")
}

Taskfile.yml

version: '3'

tasks:
  default:
    cmds:
      - task: run-logfatal
      - task: run-logpanic
  run-logfatal:
    cmds:
      - cmd: go run fatal/logfatal.go
        ignore_error: true
  run-logpanic:
    cmds:
      - cmd: go run panic/logpanic.go
        ignore_error: true

実行結果

gitpod /workspace/try-golang (master) $ task -d examples/singleapp/diff_logfatal_and_logpanic/
task: [run-logfatal] go run fatal/logfatal.go
>>> call log.Fatal
exit status 1
task: [run-logpanic] go run panic/logpanic.go
>>> call log.Panic
>>> call defer
panic: call log.Panic


goroutine 1 [running]:
log.(*Logger).Panicln(0x52ebc0?, {0xc000104f38?, 0x0?, 0x405058?})
        /home/gitpod/go/src/log/log.go:262 +0x69
main.main()
        /workspace/try-golang/examples/singleapp/diff_logfatal_and_logpanic/panic/logpanic.go:19 +0xa5
exit status 2

過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。