Golang / GoLang Production Patterns and Web Standards Interview Questions
What patterns make HTTP error handling consistent and DRY in Go?
Go HTTP handlers cannot return errors — the function signature is func(http.ResponseWriter, *http.Request). Several patterns solve this: the custom handler type, the handler error interface, or a response helper pattern.
// Pattern 1: custom handler type that returns error type HandlerFunc func(w http.ResponseWriter, r *http.Request) error func (h HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) { if err := h(w, r); err != nil { handleError(w, r, err) } } // Typed API errors type APIError struct { Status int `json:"-"` Code string `json:"code"` Message string `json:"message"` } func (e *APIError) Error() string { return e.Message } // Central error handler func handleError(w http.ResponseWriter, r *http.Request, err error) { var apiErr *APIError if errors.As(err, &apiErr) { writeJSON(w, apiErr.Status, apiErr) return } if errors.Is(err, ErrNotFound) { writeJSON(w, http.StatusNotFound, &APIError{Code: "NOT_FOUND", Message: "resource not found"}) return } // Unknown error â log and return generic 500 log.Printf("unhandled error %s %s: %v", r.Method, r.URL.Path, err) writeJSON(w, http.StatusInternalServerError, &APIError{Code: "INTERNAL", Message: "internal server error"}) } // Handler using the custom type mux.Handle("GET /users/{id}", HandlerFunc(func(w http.ResponseWriter, r *http.Request) error { id, err := strconv.Atoi(r.PathValue("id")) if err != nil { return &APIError{Status: 400, Code: "INVALID_ID", Message: "id must be an integer"} } user, err := userService.FindByID(r.Context(), id) if err != nil { return fmt.Errorf("finding user: %w", err) // wraps ErrNotFound } return writeJSON(w, http.StatusOK, user) }))
More Related questions...