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
RecoverPanicfunction must accept a functionfof typefunc() erroras its sole argument. RecoverPanicmust executefwithin adeferblock.- Inside the
deferblock, userecover()to check if a panic occurred. - If a panic is detected, log the panic value (using
fmt.Printfis 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
RecoverPanicitself should return anerror.
Expected Behavior:
- If
fruns successfully and returns an error,RecoverPanicshould return that error. - If
fruns successfully and returnsnil,RecoverPanicshould returnnil. - If
fpanics,RecoverPanicshould log the panic and return a specific error indicating a panic.
Important Edge Cases:
- What happens if
fitself callsrecover? (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
fwill always be of typefunc() error. - The
RecoverPanicfunction must be namedRecoverPanic. - Performance is not a primary concern for this challenge, but avoid unnecessary computations within the recovery logic.
- The standard Go
errorspackage should be used for creating the error.
Notes
- Remember that
deferstatements 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
deferandrecoverfor handling panics.