En aquest tema, explorarem dos conceptes importants en la gestió d'errors en Go: panic i recover. Aquests mecanismes permeten gestionar situacions excepcionals i errors crítics en les aplicacions Go.

Què és panic?

panic és una funció integrada en Go que s'utilitza per generar un error en temps d'execució. Quan es crida a panic, l'execució del programa es deté immediatament i es comença a desfer la pila de crides (stack unwinding), executant les funcions defer en el procés. Finalment, el programa es tanca.

Exemple de panic

package main

import "fmt"

func main() {
    fmt.Println("Abans del panic")
    panic("Alguna cosa va malament!")
    fmt.Println("Després del panic") // Aquesta línia no s'executarà
}

Explicació:

  • El programa imprimeix "Abans del panic".
  • La funció panic es crida amb el missatge "Alguna cosa va malament!".
  • L'execució es deté immediatament i el programa es tanca, per tant, "Després del panic" no s'imprimeix.

Què és recover?

recover és una altra funció integrada que permet recuperar-se d'un panic. Només es pot utilitzar dins d'una funció defer. Si es crida a recover fora d'una funció defer, retorna nil.

Exemple de recover

package main

import "fmt"

func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recuperat del panic:", r)
        }
    }()
    
    fmt.Println("Abans del panic")
    panic("Alguna cosa va malament!")
    fmt.Println("Després del panic") // Aquesta línia no s'executarà
}

Explicació:

  • La funció defer conté una crida a recover.
  • Quan es crida a panic, la funció defer s'executa.
  • recover captura el valor passat a panic i permet que el programa continuï executant-se després de la funció defer.

Combinació de panic i recover

La combinació de panic i recover és útil per gestionar errors crítics sense tancar completament el programa. Això permet que el programa es recuperi i continuï executant-se.

Exemple pràctic

package main

import "fmt"

func mayPanic() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recuperat del panic:", r)
        }
    }()
    
    fmt.Println("Abans del possible panic")
    panic("Alguna cosa va malament!")
    fmt.Println("Després del possible panic") // Aquesta línia no s'executarà
}

func main() {
    fmt.Println("Inici del programa")
    mayPanic()
    fmt.Println("Final del programa")
}

Explicació:

  • La funció mayPanic pot generar un panic.
  • La funció defer dins de mayPanic utilitza recover per capturar el panic i permetre que el programa continuï.
  • El programa imprimeix "Inici del programa", "Abans del possible panic", "Recuperat del panic: Alguna cosa va malament!" i "Final del programa".

Exercicis Pràctics

Exercici 1: Gestió de Panic

Escriu una funció que generi un panic si el paràmetre d'entrada és negatiu. Utilitza recover per gestionar el panic i imprimir un missatge adequat.

package main

import "fmt"

func checkPositive(n int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recuperat del panic:", r)
        }
    }()
    
    if n < 0 {
        panic("El número és negatiu!")
    }
    
    fmt.Println("El número és positiu:", n)
}

func main() {
    checkPositive(10)
    checkPositive(-5)
    checkPositive(0)
}

Solució:

package main

import "fmt"

func checkPositive(n int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recuperat del panic:", r)
        }
    }()
    
    if n < 0 {
        panic("El número és negatiu!")
    }
    
    fmt.Println("El número és positiu:", n)
}

func main() {
    checkPositive(10)  // El número és positiu: 10
    checkPositive(-5)  // Recuperat del panic: El número és negatiu!
    checkPositive(0)   // El número és positiu: 0
}

Exercici 2: Funció Segura

Escriu una funció que cridi a una altra funció que pot generar un panic. Utilitza recover per assegurar-te que el programa no es tanca.

package main

import "fmt"

func mayPanic() {
    panic("Alguna cosa va malament!")
}

func safeFunction() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recuperat del panic:", r)
        }
    }()
    
    mayPanic()
}

func main() {
    fmt.Println("Inici del programa")
    safeFunction()
    fmt.Println("Final del programa")
}

Solució:

package main

import "fmt"

func mayPanic() {
    panic("Alguna cosa va malament!")
}

func safeFunction() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recuperat del panic:", r)
        }
    }()
    
    mayPanic()
}

func main() {
    fmt.Println("Inici del programa")  // Inici del programa
    safeFunction()                     // Recuperat del panic: Alguna cosa va malament!
    fmt.Println("Final del programa")  // Final del programa
}

Conclusió

En aquest tema, hem après sobre els mecanismes panic i recover en Go per gestionar errors crítics i situacions excepcionals. Hem vist com utilitzar panic per generar errors i recover per capturar-los i permetre que el programa continuï executant-se. Aquests conceptes són essencials per escriure codi robust i resilient en Go.

© Copyright 2024. Tots els drets reservats