99 lines
3.0 KiB
Go
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"})
|
|
}
|
|
}
|