Hone logo
Hone
Problems

Go Panic Recovery

In Go, a panic is an exceptional condition that disrupts the normal flow of a program. While panics are generally meant for unrecoverable errors, there are situations where you might want to gracefully handle them and prevent your application from crashing. This challenge will guide you through implementing a robust recovery mechanism using Go's defer and recover keywords.

Problem Description

Your task is to create a Go function RecoverPanic that takes another function f as an argument. RecoverPanic should execute f and, if f panics, RecoverPanic should catch the panic, log it, and return a specific error value to indicate that a panic occurred. If f executes without panicking, RecoverPanic should simply return nil for the error.

Key Requirements:

  • The RecoverPanic function must accept a function f of type func() error as its sole argument.
  • RecoverPanic must execute f within a defer block.
  • Inside the defer block, use recover() to check if a panic occurred.
  • If a panic is detected, log the panic value (using fmt.Printf is acceptable for this challenge) and return a predefined error (e.g., errors.New("panic occurred")).
  • If no panic occurs, the function should return nil.
  • The function RecoverPanic itself should return an error.

Expected Behavior:

  • If f runs successfully and returns an error, RecoverPanic should return that error.
  • If f runs successfully and returns nil, RecoverPanic should return nil.
  • If f panics, RecoverPanic should log the panic and return a specific error indicating a panic.

Important Edge Cases:

  • What happens if f itself calls recover? (Your implementation should still handle the outer panic).
  • What if the panic value is not an error type?

Examples

Example 1:

Input: A function `f` that executes without panicking and returns `nil`.
Output: nil
Explanation: The function `f` completes normally. `RecoverPanic` detects no panic and returns nil.

Example 2:

Input: A function `f` that executes without panicking and returns `errors.New("something went wrong")`.
Output: errors.New("something went wrong")
Explanation: The function `f` completes normally and returns an error. `RecoverPanic` detects no panic and returns the error from `f`.

Example 3:

Input: A function `f` that explicitly panics with `panic("intentional error")`.
Output: errors.New("panic occurred") (and "Detected panic: intentional error" is printed to stdout)
Explanation: The function `f` panics. `RecoverPanic`'s defer function catches the panic, logs it, and returns a predefined error.

Example 4:

Input: A function `f` that panics with a non-error value, e.g., `panic(123)`.
Output: errors.New("panic occurred") (and "Detected panic: 123" is printed to stdout)
Explanation: The function `f` panics with an integer. `RecoverPanic`'s defer function catches the panic, logs the integer value, and returns a predefined error.

Constraints

  • The input function f will always be of type func() error.
  • The RecoverPanic function must be named RecoverPanic.
  • Performance is not a primary concern for this challenge, but avoid unnecessary computations within the recovery logic.
  • The standard Go errors package should be used for creating the error.

Notes

  • Remember that defer statements are executed in LIFO (Last-In, First-Out) order.
  • The recover() built-in function only works when called directly inside a deferred function.
  • Consider how you will handle different types of panic values. You might want to use a type assertion or a type switch if you need to inspect the panic value more closely, though for this challenge, simply logging it is sufficient.
  • The goal is to demonstrate the core mechanism of defer and recover for handling panics.
Loading editor...
go