ProgrammingBackend Developer

Explain the work of defer, panic and recover in Go, their interrelation in managing control flow during errors and finalization.

Pass interviews with Hintsage AI assistant

Answer.

History of the question:

The defer, panic, and recover operators are important mechanisms for managing control flow in Go. The defer operator is used for delayed function execution, panic initiates an error (abort), and recover allows intercepting the panic and continuing execution.

Problem:

Without proper use of these tools, it is difficult to correctly finalize resources and implement fault tolerance. Unpredictable function termination, unreleased resources, and uncontrolled "exit" of the application during errors are common problems with the wrong approach.

Solution:

Correct use of defer ensures safe resource release even in case of errors. panic is a mechanism for emergency termination in exceptional situations and should only be used for truly exceptional cases. recover provides the ability to "save" execution within a deferred function.

Code example:

func riskyFunction() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered in riskyFunction:", r) } }() fmt.Println("Doing some work...") panic("something bad happened!") } func main() { riskyFunction() fmt.Println("After riskyFunction") }

Key features:

  • defer is always called in reverse order before exiting the function, even in the case of panic.
  • recover only works inside deferred functions.
  • panic interrupts the execution of the current goroutine; if not caught by recover, it terminates the process.

Trick questions.

Why doesn't recover work outside of defer within the same function where panic occurred?

recover returns a non-nil value (i.e., intercepts the panic) only if called from a deferred function nested within the same function where the panic occurred. If recover is called directly, it always returns nil.

Code example:

func f() { panic("fail!") r := recover() // doesn't work! }

Can defer be called after panic and will it execute?

No. After panic, all already registered defer calls are executed, but new defers after panic will not be called, as the function execution has already "collapsed."

Can one recover from panic that occurred in another goroutine?

No, recover only works for panics in the current goroutine. If another goroutine panics and recover is not called in that same goroutine, the application will terminate.

Common mistakes and anti-patterns

  • Using panic for regular error handling.
  • Expecting recover to "catch" panics from all parts of the code.
  • Confusing the order of multiple defer calls.

Real-life example

Negative case

In the project, all errors were thrown via panic, and recovery handling was only in the main function. This led to resources not being closed, some data being lost, and logs being unreadable.

Pros:

  • Fast development, little code for error handling.

Cons:

  • Unpredictable system behavior, frequent leaks, difficult debugging.

Positive case

In every critical section, defer was used to release resources, panic was applied only for truly exceptional situations, and recover was used to isolate emergencies in non-critical parts. All error details were logged.

Pros:

  • Clear localization and handling of errors. No leaks.

Cons:

  • Need to maintain a more complex code structure, sometimes difficult to understand "where" to catch the panic.