Using `recover`
Part of the Logic & Flow section of Coddy's GO journey — lesson 43 of 68.
While panic stops your program immediately, Go provides a way to regain control through the recover function. The recover function allows you to catch a panic and handle it gracefully, preventing your entire program from crashing.
However, recover has a very specific requirement: it can only be used inside a deferred function. When a panic occurs, Go executes all deferred functions before the program terminates, giving recover a chance to intercept the panic:
func riskyFunction() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
panic("something went wrong!")
}The recover function returns the value that was passed to panic, or nil if no panic occurred. This allows you to check if a panic happened and take appropriate action, such as logging the error or performing cleanup operations.
Like panic, recover should be used sparingly in Go. It's most commonly seen in scenarios like web servers where you want to prevent a single request's panic from crashing the entire server, allowing it to continue serving other requests.
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
Challenge
EasyBuild a web server request handler that uses recover to gracefully handle panics and prevent the entire server from crashing. This challenge demonstrates how to use recover inside a deferred function to catch panics and maintain server stability.
You will receive two inputs:
- A string containing request details in the format
"endpoint,method,action"(e.g.,"/api/users,GET,process") - A string containing server configuration in the format
"server_name,max_requests"(e.g.,"WebServer,100")
Your task is to:
- Parse the first input by splitting on commas to get endpoint, method, and action
- Parse the second input by splitting on commas to get server name and max requests
- Convert the max requests string to an integer
- Create a function called
handleRequestthat takes endpoint, method, action, and server name as parameters - Inside
handleRequest, add a deferred function that usesrecoverto catch any panics:- If a panic is recovered (recover returns non-nil), print:
"Server [server_name] recovered from panic: [panic_value]" - After handling the panic, print:
"Request handling completed safely"
- If a panic is recovered (recover returns non-nil), print:
- After the deferred function, simulate request processing based on the action:
- If action is
"process": print"Processing [method] request to [endpoint]" - If action is
"panic_nil": print"Attempting dangerous operation"then callpanic("nil pointer access") - If action is
"panic_overflow": print"Attempting resource allocation"then callpanic("memory overflow") - If action is
"panic_timeout": print"Attempting database connection"then callpanic("connection timeout") - For any other action: print
"Unknown action: [action]"then callpanic("invalid action")
- If action is
- In the main function, print the server startup message:
"Starting [server_name] with max [max_requests] requests" - Call the
handleRequestfunction with the parsed parameters - After the function call, print the server status:
"Server [server_name] is still running" - Finally, print a summary:
"Server Summary:""Name: [server_name]""Max Requests: [max_requests]""Last Request: [method] [endpoint]""Action Performed: [action]""Status: Operational"
Use the strings package to split the input strings on commas and the strconv package to convert the max requests string to an integer. This challenge demonstrates how recover allows servers to handle unexpected panics gracefully, preventing individual request failures from bringing down the entire system.
Cheat sheet
The recover function allows you to catch a panic and handle it gracefully, preventing your program from crashing.
recover can only be used inside a deferred function:
func riskyFunction() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
panic("something went wrong!")
}The recover function returns the value that was passed to panic, or nil if no panic occurred. This allows you to check if a panic happened and take appropriate action.
recover is commonly used in web servers to prevent a single request's panic from crashing the entire server.
Try it yourself
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
// Read input
var requestDetails string
var serverConfig string
fmt.Scanln(&requestDetails)
fmt.Scanln(&serverConfig)
// Parse request details
requestParts := strings.Split(requestDetails, ",")
endpoint := requestParts[0]
method := requestParts[1]
action := requestParts[2]
// Parse server configuration
configParts := strings.Split(serverConfig, ",")
serverName := configParts[0]
maxRequests, _ := strconv.Atoi(configParts[1])
// TODO: Write your code below
// Create the handleRequest function with recover mechanism
// Print server startup message
// Call handleRequest function
// Print server status and summary
}This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Advanced Control Flow
Switch with `fallthrough`Breaking from Nested LoopsContinuing a Specific LoopThe `goto` StatementRecap - Advanced Loop Control4Project: Simple Task List
Project SetupAdding a Task7Error Handling In-Depth
Custom Error TypesWrapping Errors with `%w`Unwrapping with `errors.Is`Unwrapping with `errors.As`Understanding `panic`Using `recover`Recap - Safe Division2Structs and Methods
Defining Methods on StructsValue ReceiversPointer ReceiversChoosing ReceiversMethods vs FunctionsRecap - Struct Behavior5Maps In-Depth
Maps of StructsPointers as Map ValuesTesting for Nil MapsComparing MapsRecap - Word Frequency Counter3Interfaces (The Basics)
What is an Interface?Defining an InterfaceImplementing an InterfaceUsing Interface TypesEmpty InterfaceType AssertionsType SwitchRecap - Shapes and Behaviors