Files
FamilyHUB/backend/src/api/routers/errors.go
T

99 lines
3.0 KiB
Go

package routers
import (
"FamilyHub/src/api/dto"
"FamilyHub/src/api/requests"
"FamilyHub/src/api/services"
receiptServiceIntegration "FamilyHub/src/integrations/receiptProvider"
"database/sql"
"errors"
"log"
"net/http"
"runtime/debug"
"github.com/gin-gonic/gin"
)
func logError(c *gin.Context, scope string, err error) {
log.Printf(
"%s failed: method=%s path=%s route=%s error=%v",
scope,
c.Request.Method,
c.Request.URL.Path,
c.FullPath(),
err,
)
}
func logInternalError(c *gin.Context, scope string, err error) {
log.Printf(
"%s failed: method=%s path=%s route=%s error=%v\n%s",
scope,
c.Request.Method,
c.Request.URL.Path,
c.FullPath(),
err,
debug.Stack(),
)
}
func handleReceiptError(c *gin.Context, err error) {
var externalErr *receiptServiceIntegration.ExternalServiceError
switch {
case errors.Is(err, receiptServiceIntegration.ErrReceiptNotFound):
c.JSON(http.StatusNotFound, dto.ErrorResponse{Message: err.Error()})
case errors.As(err, &externalErr):
log.Printf(
"receipt external service error: method=%s path=%s upstream_status=%d upstream_body=%q",
c.Request.Method,
c.Request.URL.Path,
externalErr.StatusCode,
externalErr.Body,
)
logError(c, "receipt external service", err)
switch externalErr.StatusCode {
case http.StatusForbidden, http.StatusTooManyRequests:
c.JSON(http.StatusServiceUnavailable, dto.ErrorResponse{Message: "receipt service temporarily unavailable"})
default:
c.JSON(http.StatusBadGateway, dto.ErrorResponse{Message: "receipt service error"})
}
default:
logInternalError(c, "receipt request", err)
c.JSON(http.StatusInternalServerError, dto.ErrorResponse{Message: "internal server error"})
}
}
func handleActivityError(c *gin.Context, err error) {
logInternalError(c, "activity request", err)
c.JSON(http.StatusInternalServerError, dto.ErrorResponse{Message: "internal server error"})
}
func handleFamilyError(c *gin.Context, err error) {
switch {
case errors.Is(err, services.ErrFamilyNotFound):
c.JSON(http.StatusNotFound, dto.ErrorResponse{Message: err.Error()})
case errors.Is(err, sql.ErrNoRows):
c.JSON(http.StatusNotFound, dto.ErrorResponse{Message: "family not found"})
case errors.Is(err, requests.ErrFamilyNameRequired):
c.JSON(http.StatusBadRequest, dto.ErrorResponse{Message: err.Error()})
default:
logInternalError(c, "family request", err)
c.JSON(http.StatusInternalServerError, dto.ErrorResponse{Message: "internal server error"})
}
}
func handleUserError(c *gin.Context, err error) {
switch {
case errors.Is(err, services.ErrUserNotFound):
c.JSON(http.StatusNotFound, dto.ErrorResponse{Message: err.Error()})
case errors.Is(err, services.ErrInvalidPatch):
c.JSON(http.StatusBadRequest, dto.ErrorResponse{Message: err.Error()})
case errors.Is(err, services.ErrTelegramIDMissing):
c.JSON(http.StatusBadRequest, dto.ErrorResponse{Message: err.Error()})
default:
logInternalError(c, "user request", err)
c.JSON(http.StatusInternalServerError, dto.ErrorResponse{Message: "internal server error"})
}
}