Unified error handling is implemented through middleware and the ErrorResponse structure, capturing panics and standardizing responses. The middleware uses defer and recover to prevent crashes, and the writeError function simplifies error returns, ensuring consistent and maintainable API error responses when integrated with routing.

In Go language development for web services, unified error handling is key to ensuring consistency and maintainability of API responses. Through middleware mechanisms, we can centrally handle errors in HTTP requests and return a standardized error response format, avoiding scattered error handling code.
Please open in WeChat client
Unified Error Response Structure
Define a common error response format for easy parsing by the frontend and logging.
type ErrorResponse struct { Code int `json:"code"` Message string `json:"message"` Data any `json:"data,omitempty"`}
This structure includes a status code, description, and an optional data field. Fields can be extended based on business needs, such as adding a request ID or timestamp.
Error Handling Middleware Implementation
The middleware captures panics and explicit errors during processing and converts them to a unified format for return.
func ErrorHandlingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Capture panic defer func() { if err := recover(); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(ErrorResponse{ Code: http.StatusInternalServerError, Message: "Internal server error", }) } }() // Call the next handler next.ServeHTTP(w, r) })}
This middleware uses defer and recover to capture runtime panics, preventing service crashes while ensuring errors can be formatted and returned.
Helper Function for Actively Returning Errors
Provides utility functions for handlers to easily return unified errors.
func writeError(w http.ResponseWriter, code int, message string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(code) json.NewEncoder(w).Encode(ErrorResponse{ Code: code, Message: message, })} // Usage in handler func userHandler(w http.ResponseWriter, r *http.Request) { user, err := getUser(r.Context()) if err != nil { writeError(w, http.StatusNotFound, "User not found") return } json.NewEncoder(w).Encode(user)}
By encapsulating the writeError function, business logic can quickly return standard errors, reducing duplicate code.
Integration into HTTP Service
Apply the middleware to the router for global error handling.
func main() { mux := http.NewServeMux() mux.HandleFunc("/user", userHandler) handler := ErrorHandlingMiddleware(mux) http.ListenAndServe(":8080", handler)}
All requests passing through this middleware will be protected by error handling, even unhandled panics will be caught.
That’s basically it. A concise error middleware along with helper functions can provide clear and consistent error output for Go’s HTTP services. It’s not complicated but easy to overlook details, such as setting Content-Type and the correct use of defer.
This concludes the detailed content on Golang HTTP error handling with a unified error response middleware. For more, please follow our public account for other related articles!