log.Fatal în Go

Scrie mesajul în jurnal și oprește imediat programul cu codul 1 (ca log.Print urmat de os.Exit(1)).

Sintaxă
func Fatal(v ...any)
func Fatalf(format string, v ...any)
func Fatalln(v ...any)

Ce face log.Fatal

log.Fatal, log.Fatalf și log.Fatalln scriu mesajul exact ca Print, Printf și Println, apoi apelează os.Exit(1). Se folosesc pentru erori după care programul nu poate continua: lipsește fișierul de configurare, portul este ocupat.

Ca la os.Exit, funcțiile amânate cu defer NU mai rulează: fișierele nu se închid, buffer-ele nu se golesc. Folosește-le doar în main (sau în init), niciodată în funcții de bibliotecă: acolo returnezi o eroare.

Parametri

Parametru Descriere
v Valorile mesajului.
format La Fatalf: șablonul mesajului.

Ce returnează

Nu se întoarce niciodată: programul se oprește cu codul de ieșire 1.

Exemple

Exemplul 1: Oprire când lipsește configurarea

package main

import (
    "log"
    "os"
)

func main() {
    date, err := os.ReadFile("setari.json")
    if err != nil {
        log.Fatalf("nu pot citi configurarea: %v", err)
    }
    log.Println("configurare încărcată:", len(date), "octeți")
}

Rezultat în terminal

$ go run .
2025/03/14 10:30:00 nu pot citi configurarea: open setari.json: no such file or directory
exit status 1

Exemplul 2: Codul de ieșire și defer-ul care nu rulează

Programul se pornește pe el însuși ca proces copil (cu argumentul copil), ca să putem vedea ce scrie copilul și cu ce cod se oprește.

package main

import (
    "errors"
    "fmt"
    "log"
    "os"
    "os/exec"
)

func main() {
    if len(os.Args) > 1 && os.Args[1] == "copil" {
        log.SetFlags(0)
        defer fmt.Println("defer: închid baza de date") // nu apare
        log.Fatalln("portul 8080 este ocupat")
    }

    exe, _ := os.Executable()
    iesire, err := exec.Command(exe, "copil").CombinedOutput()
    fmt.Printf("copilul a scris: %q\n", iesire)
    var ee *exec.ExitError
    if errors.As(err, &ee) {
        fmt.Println("cod de ieșire:", ee.ExitCode())
    }
}

Rezultat

copilul a scris: "portul 8080 este ocupat\n"
cod de ieșire: 1

Greșeli frecvente

  • Apelezi log.Fatal într-o funcție care ar putea fi folosită și altfel (într-un server, într-un test). Tot programul se oprește; returnează o eroare și lasă main să decidă.
  • Pui log.Fatal după ce ai deschis fișiere sau ai început tranzacții, cu defer pentru curățenie. Defer-urile sunt sărite.
  • Folosești log.Fatal în teste. Oprește tot procesul de test; folosește t.Fatal.

Comenzi înrudite

  • os.Exit: Oprește imediat programul cu codul de ieșire dat; funcțiile amânate cu defer nu mai rulează.
  • log.Panic: Scrie mesajul în jurnal și apoi declanșează un panic cu același mesaj.
  • log.Println: Scrie un mesaj în jurnal, precedat de dată și oră; Println pune spații între valori, Print ca fmt.Print.
  • testing.T.Fatal: Marchează testul ca eșuat, scrie mesajul și oprește imediat testul curent; celelalte teste continuă.