package middleware import ( "errors" "fmt" "net/http" "github.com/labstack/echo/v5" ) // ErrorResponse represents a standardized error response type ErrorResponse struct { Error string `json:"error"` Message string `json:"message,omitempty"` Code string `json:"code,omitempty"` } // HTTPError represents an HTTP error with additional context type HTTPError struct { Code int Message string Err error } // Error implements the error interface func (e *HTTPError) Error() string { if e.Err != nil { return fmt.Sprintf("%s: %v", e.Message, e.Err) } return e.Message } // Common error types var ( ErrBadRequest = &HTTPError{Code: http.StatusBadRequest, Message: "Bad request"} ErrUnauthorized = &HTTPError{Code: http.StatusUnauthorized, Message: "Unauthorized"} ErrForbidden = &HTTPError{Code: http.StatusForbidden, Message: "Forbidden"} ErrNotFound = &HTTPError{Code: http.StatusNotFound, Message: "Resource not found"} ErrConflict = &HTTPError{Code: http.StatusConflict, Message: "Resource conflict"} ErrTooManyRequest = &HTTPError{Code: http.StatusTooManyRequests, Message: "Too many requests"} ErrInternal = &HTTPError{Code: http.StatusInternalServerError, Message: "Internal server error"} ) // NewHTTPError creates a new HTTP error func NewHTTPError(code int, message string, err error) *HTTPError { return &HTTPError{ Code: code, Message: message, Err: err, } } // RespondWithError sends a standardized error response func RespondWithError(c *echo.Context, code int, message string, err error) error { response := ErrorResponse{ Error: message, Message: "", Code: "", } // Include original error message in development mode if available if err != nil { response.Message = err.Error() } return c.JSON(code, response) } // RespondWithHTTPError sends an HTTPError as JSON func RespondWithHTTPError(c *echo.Context, httpErr *HTTPError) error { response := ErrorResponse{ Error: httpErr.Message, } if httpErr.Err != nil { response.Message = httpErr.Err.Error() } return c.JSON(httpErr.Code, response) } // WrapHandler wraps an echo.HandlerFunc to return standardized errors func WrapHandler(fn func(*echo.Context) error) echo.HandlerFunc { return func(c *echo.Context) error { err := fn(c) if err != nil { if httpErr, ok := errors.AsType[*HTTPError](err); ok { return RespondWithHTTPError(c, httpErr) } return RespondWithError(c, http.StatusInternalServerError, "Internal server error", err) } return nil } }