Files
DocNest/backend/internal/handlers/errors.go
M1ngdaXie c84cbafb2c Refactor and improve code consistency across multiple files
- Enhanced SQL queries in `session.go` and `share.go` for clarity and consistency.
- Updated comments for better understanding and maintenance.
- Ensured consistent error handling and return statements across various methods.
2026-02-04 22:01:47 -08:00

96 lines
2.9 KiB
Go

package handlers
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
// ErrorResponse represents a standardized error response
type ErrorResponse struct {
Error string `json:"error"`
Message string `json:"message,omitempty"`
Details map[string]interface{} `json:"details,omitempty"`
}
// respondWithError sends a standardized error response
func respondWithError(c *gin.Context, statusCode int, errorType string, message string) {
c.JSON(statusCode, ErrorResponse{
Error: errorType,
Message: message,
})
}
// respondWithValidationError parses validation errors and sends detailed response
func respondWithValidationError(c *gin.Context, err error) {
details := make(map[string]interface{})
// Try to parse validator errors
if validationErrors, ok := err.(validator.ValidationErrors); ok {
for _, fieldError := range validationErrors {
fieldName := fieldError.Field()
switch fieldError.Tag() {
case "required":
details[fieldName] = "This field is required"
case "oneof":
details[fieldName] = fmt.Sprintf("Must be one of: %s", fieldError.Param())
case "email":
details[fieldName] = "Must be a valid email address"
case "uuid":
details[fieldName] = "Must be a valid UUID"
default:
details[fieldName] = fmt.Sprintf("Validation failed on '%s'", fieldError.Tag())
}
}
} else {
// Generic validation error
details["message"] = err.Error()
}
c.JSON(http.StatusBadRequest, ErrorResponse{
Error: "validation_error",
Message: "Invalid input",
Details: details,
})
}
// respondBadRequest sends a 400 Bad Request error
func respondBadRequest(c *gin.Context, message string) {
respondWithError(c, http.StatusBadRequest, "bad_request", message)
}
// respondUnauthorized sends a 401 Unauthorized error
func respondUnauthorized(c *gin.Context, message string) {
respondWithError(c, http.StatusUnauthorized, "unauthorized", message)
}
// respondForbidden sends a 403 Forbidden error
func respondForbidden(c *gin.Context, message string) {
respondWithError(c, http.StatusForbidden, "forbidden", message)
}
// respondNotFound sends a 404 Not Found error
func respondNotFound(c *gin.Context, resource string) {
message := fmt.Sprintf("%s not found", resource)
if resource == "" {
message = "Resource not found"
}
respondWithError(c, http.StatusNotFound, "not_found", message)
}
// respondInternalError sends a 500 Internal Server Error
// In production, you may want to log the actual error but not expose it to clients
func respondInternalError(c *gin.Context, message string, err error) {
// Log the actual error for debugging (you can replace with proper logging)
if err != nil {
fmt.Printf("Internal error: %v\n", err)
}
respondWithError(c, http.StatusInternalServerError, "internal_error", message)
}
func respondInvalidID(c *gin.Context, message string) {
respondWithError(c, http.StatusBadRequest, "invalid_id", message)
}