Terminating or Aborting an HTTP Request
To handle errors during API handling, it's crucial to terminate or abort the request. While options like log.fatal and os.Exit may terminate the entire service, they hinder the delivery of error messages. This article explores alternative approaches using panic, defer, recover, and return.
Error Handling with return
The simplest method is to return from the ServeHTTP() function:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // Check parameters if !ok { str := `{"Result":"","Error":"Invalid Parameters"}` fmt.Fprint(w, str) return // Terminates the request } // Normal API handling })
This approach works well for the main HTTP handler function, but within nested functions, it only exists the function, not the caller.
HTTP Error Codes and Custom Responses
Instead of the default 200 OK response code, consider returning an appropriate HTTP error code. http.Error() allows for customized error messages:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if !ok { http.Error(w, `Invalid Input Parameters!`, http.StatusBadRequest) return } // Normal API handling })
For more granular control, you can set a custom content type and response body:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if !ok { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) str := `{"Result":"","Error":"Invalid Input Parameters"}` fmt.Fprint(w, str) return } // Normal API handling })
Error Propagation with defer and recover
If error detection occurs outside of ServeHTTP(), defer and recover can be used to propagate the error state to the main handler:
type params struct { // Parameter fields } func decodeParams(r *http.Request) (*params, error) { p := new(params) defer func() { if r := recover(); r != nil { log.Println(r) return } }() // Parameter decoding if !ok { panic(errors.New("Invalid Parameters")) } return p, nil } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { p, err := decodeParams(r) if err != nil { http.Error(w, `Invalid Input Parameters!`, http.StatusBadRequest) return } // Normal API handling })
In this approach, defer registers a cleanup function that ensures the recover() function will be executed regardless of the function's return or panic. If decodeParams detects an invalid parameter, it panics, effectively returning an error from ServeHTTP() and allowing it to return the error message.
The above is the detailed content of How to Gracefully Handle and Terminate HTTP Requests in Go?. For more information, please follow other related articles on the PHP Chinese website!