Update all middleware functions to use *echo.Context (pointer) instead of echo.Context (value) as required by Echo v5. Changes in device_auth.go: - Update DeviceAuthMiddleware() signature (line 38) - Update validateDeviceAuth() signature (line 170) - Update RequireDeviceAuth() signature (line 212) Changes in error_handler.go: - Update RespondWithError() signature (line 44) - Update RespondWithHTTPError() signature (line 69) - Update WrapHandler() to accept *echo.Context (line 82) - Fix context passing in WrapHandler() (c is already pointer) Changes in rate_limiter.go: - Update RateLimiterMiddleware() signature (line 102) Changes in request_tracing.go: - Update RequestTracingMiddleware() signature (line 48) - Fix Response() dereference for v5 API (line 264) - Use *c.Response() to get http.ResponseWriter Changes in security.go: - Update SecurityHeadersMiddleware() signature (line 14) Changes in device_auth_test.go: - Update test helper signatures Changes in middleware_test.go: - Remove unused import All middleware now properly implements Echo v5's pointer-based context pattern.
94 lines
2.5 KiB
Go
94 lines
2.5 KiB
Go
package middleware
|
|
|
|
import (
|
|
"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 := err.(*HTTPError); ok {
|
|
return RespondWithHTTPError(c, httpErr)
|
|
}
|
|
return RespondWithError(c, http.StatusInternalServerError, "Internal server error", err)
|
|
}
|
|
return nil
|
|
}
|
|
}
|