Golang Defer Panic And Recover Complete Guide

 Last Update:2025-06-22T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    7 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of GoLang Defer, Panic, and Recover

Defer

The defer statement in Go schedules a function call to be run after the surrounding function returns. It is typically used for cleanup activities such as releasing resources or closing files. Multiple defer calls are stacked, meaning they are executed in the reverse order they were declared (similar to Last-In-First-Out - LIFO).

Syntax:

defer functionName()

or if you need to pass arguments:

defer functionName(args...)

Example:

package main

import "fmt"

func main() {
    defer fmt.Println("World")
    fmt.Println("Hello")
}
// Output:
// Hello
// World

In this case, "World" is printed last because of the defer statement.

Another example where multiple defer statements are used:

package main

import "fmt"

func main() {
    defer fmt.Println("One")
    defer fmt.Println("Two")
    defer fmt.Println("Three")
    
    fmt.Println("Start")
}
// Output:
// Start
// Three
// Two
// One

Panic

A panic in Go is a built-in function that stops the normal flow of control and begins panicking. When a function panics, it immediately stops executing and returns to its caller. This process continues up the call stack until all deferred functions have been executed. Panics are usually used for serious conditions like invalid data, system issues, or critical errors that should stop program execution.

Syntax:

panic("message")

Example:

package main

import "fmt"

func causePanic() {
    panic("Something bad happened!")
}

func main() {
    defer fmt.Println("Defer statement executed before panic")

    causePanic()
    fmt.Println("This will not be printed")
}

Output will be:

Defer statement executed before panic
panic: Something bad happened!

goroutine 1 [running]:
main.causePanic(...)
    /path/to/code/main.go:6
main.main()
    /path/to/code/main.go:11 +0x99

Recover

recover is another built-in function designed to catch panics. It can only be successfully called inside a deferred function. If the deferred function was started by a panic, recover will return the value passed to the panic function. If no panic occurred during deferred function execution, recover will return nil.

Syntax:

recover()

Example:

package main

import "fmt"

func catchPanic() {
    if r := recover(); r != nil {
        fmt.Println("Recovered from panic:", r)
    }
}

func causePanic() {
    panic("Oopsie! A panic occurred.")
}

func main() {
    defer catchPanic()  // Ensure catchPanic runs after causePanic, even if it panics

    causePanic()
    fmt.Println("This will not be printed unless recover is successful")
}
// Output:
// Recovered from panic: Oopsie! A panic occurred.

Important Information

  • Defer: Ideal for resource management tasks, ensures that functions like file closures or unlocking mechanisms are invoked correctly regardless of the function’s return path.

  • Panic: Used for handling unexpected issues that should prevent further program execution. Unlike exceptions in other languages, panic does not imply failure in normal usage and can be used for conditions that aren't expected to occur.

  • Recover: Essential for capturing and controlling panics, allowing the program to exit gracefully or attempt recovery. recover must be called from a deferred function in order to be effective.

  • Combined Usage: The combination of defer and recover can provide powerful error handling mechanisms. By deferring the recovery logic, we ensure that any panics within a function can be caught and managed.

Best Practices:

  • Use defer early in your function to manage resources.
  • Utilize panic only for true emergencies; errors should often return error values.
  • Use recover strategically to handle potential panics, especially in server or long-running processes.

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement GoLang Defer, Panic, and Recover

Understanding defer

defer is a keyword in GoLang that schedules a function call to be run after the function completes. defer is typically used for cleanup actions like closing file descriptors, releasing resources, etc.

Example 1: Basic Usage of defer

package main

import (
	"fmt"
)

func main() {
	defer fmt.Println("This will be printed last.")
	fmt.Println("This will be printed first.")
	fmt.Println("This will be printed second.")
}

Output:

This will be printed first.
This will be printed second.
This will be printed last.

In this example, the defer statement schedules the function fmt.Println("This will be printed last.") to be executed after the main function finishes executing.

Example 2: Multiple defer Statements

package main

import (
	"fmt"
)

func main() {
	defer fmt.Println("This will be printed third.")
	defer fmt.Println("This will be printed second.")
	defer fmt.Println("This will be printed first.")
	fmt.Println("This will be printed now.")
}

Output:

This will be printed now.
This will be printed first.
This will be printed second.
This will be printed third.

Here, multiple defer statements are used, and they are executed in LIFO (Last In, First Out) order.

Understanding panic

panic is a built-in function in Go that stops the ordinary flow of control and starts panicking. When a function panics, it immediately stops executing and returns to its caller. If the caller is also panicking, the program will terminate.

Example 1: Basic Usage of panic

package main

import (
	"fmt"
)

func main() {
	fmt.Println("This will be printed.")
	panic("Something bad happened!")
	fmt.Println("This will NOT be printed.")
}

Output:

This will be printed.
panic: Something bad happened!

goroutine 1 [running]:
main.main()
        /path/to/your/file.go:8 +0x6c
exit status 2

Here, the panic function is called, and the program terminates with a panic message.

Understanding recover

recover is a built-in function that regains control of a panicking goroutine. recover is usually used only inside a deferred function. By calling recover inside a deferred function, you can catch a panic and handle it gracefully.

Example 1: Basic Usage of recover

package main

import (
	"fmt"
)

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered from panic:", r)
		}
	}()

	fmt.Println("This will be printed.")
	panic("Something bad happened!")
	fmt.Println("This will NOT be printed.")
}

Output:

This will be printed.
Recovered from panic: Something bad happened!

In this example, the deferred function catches the panic using recover and prints a recovery message. This prevents the program from terminating abruptly.

Combining defer, panic, and recover

Example 1: Managing Panics with defer and recover

package main

import (
	"fmt"
)

func riskyFunction() {
	fmt.Println("Starting riskyFunction...")
	panic("Oops! An error occurred.")
	fmt.Println("This will NOT be printed.")
}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered from panic:", r)
		}
	}()

	fmt.Println("Starting main...")
	riskyFunction()
	fmt.Println("This will NOT be printed.")
}

Output:

Starting main...
Starting riskyFunction...
Recovered from panic: Oops! An error occurred.

In this example, main calls riskyFunction, which panics. The deferred function in main catches the panic and prints a recovery message.

Conclusion

Top 10 Interview Questions & Answers on GoLang Defer, Panic, and Recover

1. What is defer in Go, and how does it work?

Answer: In Go, defer is a keyword used to ensure that a function call is performed later in a program’s execution, just before the surrounding function returns, regardless of success or failure. This is particularly useful for cleanup activities such as closing files or releasing resources.

Example:

func readFromFile() {
    file, err := os.Open("example.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close() // Ensures that the file is closed when readFromFile returns
    // Rest of the code that reads from the file...
}

2. How does defer handle multiple function calls?

Answer: When multiple defer statements are present in a function, they are executed in the reverse order (LIFO). This mimics the behavior of a stack, where the last deferred function is executed first.

Example:

func multipleDefers() {
    fmt.Println("Start")
    defer fmt.Println(1)
    defer fmt.Println(2)
    defer fmt.Println(3)
    fmt.Println("End")
}
// Output:
// Start
// End
// 3
// 2
// 1

3. What is panic in Go, and how is it used?

Answer: panic is a built-in function in Go that stops the normal flow of control and begins panicking. When a function calls panic, it executes all deferred functions and then returns to the caller. This process continues up the call stack until all functions in the stack have returned. If a panic reaches the top of the stack without encountering a recover, the program crashes and prints a traceback.

Example:

func triggerPanic() {
    fmt.Println("Starting function")
    panic("Something went wrong!")
    fmt.Println("Ending function") // This line is not executed
}

4. Can you provide an example of how recover is used with panic?

Answer: recover is a built-in function that regains control of a panicking goroutine. It can only be used within a defer function as calling recover in a normal function will have no effect because it will not be able to catch the panic once it has been triggered.

Example:

func safeDivision(num, denom int) int {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from error", r)
        }
    }()
    result := num / denom
    return result
}

func main() {
    fmt.Println(safeDivision(10, 2)) // Outputs: 5
    fmt.Println(safeDivision(10, 0)) // Outputs: Recovered from error runtime error: integer divide by zero
                                     //          0
}

5. What is the difference between panic and recover?

Answer: panic is used to stop the control flow of a program and start panicking, while recover is used to regain control of a panicking goroutine by catching the panic. recover will return the error passed to panic or nil if no panic occurred.

6. Is it common to use defer, panic, and recover in Go for error handling?

Answer: While defer is commonly used for cleanup and ensuring resources are released properly, panic and recover are not generally used for normal error handling. Instead, Go encourages using multiple return values and error handling for regular error scenarios. However, panic and recover are appropriate for handling truly exceptional cases where the application cannot continue running as expected.

7. What is the significance of defer statements in a function that has a return statement?

Answer: defer statements are executed before the function returns, even if the function has a return statement. This is because defer functions are scheduled to run before the return statement actually executes.

Example:

func deferredReturn() int {
    x := 5
    defer func() {
        x++
    }()
    return x // The return value is assigned to x, then the deferred function is executed
}
fmt.Println(deferredReturn()) // Outputs: 5

8. When should you use panic in Go?

Answer: panic should be used sparingly and only in cases where something truly unforeseen happens and the application cannot continue running effectively. For instance, encountering an unrecoverable error in core system software or a critical part of an application where the system cannot remain in an undefined state.

9. How does recover help prevent a program from crashing?

Answer: recover helps prevent a program from crashing by catching a panic and providing a way to handle the error gracefully. If a panic occurs and is not caught by a recover call, the program will crash. By using recover, the program can log the error, clean up resources, or revert to a known safe state without terminating unexpectedly.

10. Can recover catch a panic from a different goroutine?

Answer: No, recover can only catch panics from the goroutine in which it is deferred. Panics in other goroutines do not affect the current goroutine and cannot be caught using recover.

You May Like This Related .NET Topic

Login to post a comment.