How to implement error handling and recovery in HTTP middleware in Go?

To implement error handling and recovery in HTTP middleware in Go, you can use the built-in recover() function along with a custom middleware handler. Here's an example:

  1. Create a custom errorHandler middleware handler that wraps your main handler:
type errorHandler struct { handler http.Handler } func (eh errorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { // Handle the error, log, or return a custom error response log.Println("Recovering from error:", err) // You can also send a custom error response // w.WriteHeader(http.StatusInternalServerError) // w.Write([]byte("Internal Server Error")) } }() // Call the main handler eh.handler.ServeHTTP(w, r) }
  1. Create your main handler function that will be wrapped by the custom middleware:
func helloHandler(w http.ResponseWriter, r *http.Request) { // Generate a panic to simulate an error panic("Something went wrong") // Your normal handler logic goes here... w.WriteHeader(http.StatusOK) w.Write([]byte("Hello, world!")) }
  1. Use the custom middleware handler in your main application:
func main() { // Create a new router router := http.NewServeMux() // Wrap the main handler with the errorHandler middleware errorHandlerMiddleware := errorHandler{handler: http.HandlerFunc(helloHandler)} // Apply the middleware to your router router.Handle("/", errorHandlerMiddleware) // Start the server log.Fatal(http.ListenAndServe(":8080", router)) }

With this setup, any panic that occurs within the helloHandler function will be caught by the middleware's recover() function. You can then handle the error as needed, log it, and return a custom error response if desired.