Sobes.tech
Middle

How can you handle panic using defer and recovery in Go?

sobes.tech AI

Answer from AI

Yes, it is possible. The panic/recover mechanism in Go allows you to catch a panic and continue executing the program.

This is done using the defer statement together with the recover() function.

  1. defer postpones the execution of a function until the current function exits, regardless of whether it exits normally or due to a panic.
  2. recover() is used inside a defer-function. If recover() is called inside a function that is running as a result of a panic, it returns the value passed to panic(). Otherwise, it returns nil.

Example:

package main

import (
	"fmt"
)

func mayPanic() {
	// A panic may occur here
	fmt.Println("Executing a function that may panic...")
	panic("Something went wrong!") // Trigger a panic
	fmt.Println("This line will not be executed after a panic")
}

func main() {
	// Defer an anonymous function until main exits
	defer func() {
		// recover() is called inside a deferred function
		if r := recover(); r != nil {
			// If recover() returns non-nil, a panic occurred
			fmt.Println("Panic caught:", r)
			// Actions like logging or recovery can be performed here
		}
	}() // Call the deferred function

	fmt.Println("Before calling mayPanic()")
	mayPanic() // Call the function that causes a panic
	fmt.Println("After calling mayPanic() (this line will not be executed if panic is not recovered)")

	fmt.Println("Program continues after panic recovery")
}

In this example:

  • mayPanic triggers a panic.
  • In main, a deferred function is declared using defer.
  • Inside the deferred function, recover() is called.
  • When mayPanic triggers a panic, the execution of main is interrupted, but before exiting, the deferred function runs.
  • recover() catches the panic, returning the value "Something went wrong!", and the program inside the deferred function continues.
  • After the deferred function completes, the program continues execution immediately after the call to mayPanic (in this case, the end of main).

Important to remember:

  • recover() only works inside functions called via defer.
  • If recover() is called outside of a deferred function, it returns nil.
  • Catching panics with recover should be used cautiously, mainly for handling unexpected errors or recovering from unrecoverable states, not as a regular error handling mechanism. In most cases, error handling should be done using multiple return values (value + error).