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:
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)
}
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!"))
}
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.