ProgrammingSenior Go Developer

Explain how Go implements the built-in functions recover and panic. What is the correct order of their usage for safe recovery in a goroutine?

Pass interviews with Hintsage AI assistant

Answer

In Go, panic is used to signal a fatal error in the program. After a panic is invoked, the execution begins to unwind the stack and call all deferred functions. If there is a function in the stack that has called recover(), it can intercept and handle the panic — but recover only works within its own goroutine and only if called from defer.

The recommended pattern for safe recovery:

func safe(fn func()) { defer func() { if r := recover(); r != nil { fmt.Println("Recovered from panic:", r) } }() fn() } go safe(func() { panic("fail!") // does not stop the program })

It's important to remember that:

  • Panic terminates the execution of the current goroutine up to the first recover
  • Recover only works when called from defer within the same goroutine
  • If recover is not used, a panic will cause the entire program to terminate

Trick Question

Can recover catch a panic that occurred in another goroutine?

Answer: No, recover only works within the goroutine where the panic occurred, and only if invoked in a deferred function. If a panic originated in one goroutine and recover is called in another — interception will not occur, and the program will terminate abnormally.

Example:

func main() { go func() { panic("inside goroutine") }() time.Sleep(time.Second) recover() // Will not work! Panic will terminate the program }

Examples of Real Errors Due to Lack of Knowledge of the Topic


Story

A developer implemented error handling using the pattern defer recover() only in the main function. When a panic occurred inside a worker in a separate goroutine, the entire program crashed — the error was not caught by the global recover.


Story

In a project, defer/recover was used for graceful shutdown of the web server, believing that this would suffice. It turned out that a panic in one of the goroutines finished the entire process because the recover handling was not in the right place — the entire worker pool had to be refactored.


Story

In the message processing thread, a panic occurred due to incorrect operation of a user function. The developer expected that it would be caught by the top-level recover, but did not realize that recover works ONLY from defer. As a result, the service crashed irregularly when an invalid message appeared in the queue.