170 lines
4.6 KiB
Go
170 lines
4.6 KiB
Go
package error_handler
|
|
|
|
import (
|
|
"acc-server-manager/local/utl/logging"
|
|
"fmt"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
type ControllerErrorHandler struct {
|
|
errorLogger *logging.ErrorLogger
|
|
}
|
|
|
|
func NewControllerErrorHandler() *ControllerErrorHandler {
|
|
return &ControllerErrorHandler{
|
|
errorLogger: logging.GetErrorLogger(),
|
|
}
|
|
}
|
|
|
|
type ErrorResponse struct {
|
|
Error string `json:"error"`
|
|
Code int `json:"code,omitempty"`
|
|
Details map[string]string `json:"details,omitempty"`
|
|
}
|
|
|
|
func (ceh *ControllerErrorHandler) HandleError(c *fiber.Ctx, err error, statusCode int, context ...string) error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
|
|
_, file, line, _ := runtime.Caller(1)
|
|
file = strings.TrimPrefix(file, "acc-server-manager/")
|
|
|
|
contextStr := ""
|
|
if len(context) > 0 {
|
|
contextStr = fmt.Sprintf("[%s] ", strings.Join(context, "|"))
|
|
}
|
|
|
|
cleanErrorMsg := strings.ReplaceAll(err.Error(), "\x00", "")
|
|
|
|
ceh.errorLogger.LogWithContext(
|
|
fmt.Sprintf("CONTROLLER_ERROR [%s:%d]", file, line),
|
|
"%s%s",
|
|
contextStr,
|
|
cleanErrorMsg,
|
|
)
|
|
|
|
errorResponse := ErrorResponse{
|
|
Error: cleanErrorMsg,
|
|
Code: statusCode,
|
|
}
|
|
|
|
if c != nil {
|
|
if errorResponse.Details == nil {
|
|
errorResponse.Details = make(map[string]string)
|
|
}
|
|
|
|
func() {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
return
|
|
}
|
|
}()
|
|
|
|
errorResponse.Details["method"] = c.Method()
|
|
errorResponse.Details["path"] = c.Path()
|
|
|
|
if ip := c.IP(); ip != "" {
|
|
errorResponse.Details["ip"] = ip
|
|
} else {
|
|
errorResponse.Details["ip"] = "unknown"
|
|
}
|
|
}()
|
|
}
|
|
|
|
if c == nil {
|
|
return fmt.Errorf("cannot return HTTP response: context is nil")
|
|
}
|
|
|
|
if statusCode >= 500 {
|
|
return c.Status(statusCode).JSON(ErrorResponse{
|
|
Error: "Internal server error",
|
|
Code: statusCode,
|
|
})
|
|
}
|
|
|
|
return c.Status(statusCode).JSON(errorResponse)
|
|
}
|
|
|
|
func (ceh *ControllerErrorHandler) HandleValidationError(c *fiber.Ctx, err error, field string) error {
|
|
return ceh.HandleError(c, err, fiber.StatusBadRequest, "VALIDATION", field)
|
|
}
|
|
|
|
func (ceh *ControllerErrorHandler) HandleDatabaseError(c *fiber.Ctx, err error) error {
|
|
return ceh.HandleError(c, err, fiber.StatusInternalServerError, "DATABASE")
|
|
}
|
|
|
|
func (ceh *ControllerErrorHandler) HandleAuthError(c *fiber.Ctx, err error) error {
|
|
return ceh.HandleError(c, err, fiber.StatusUnauthorized, "AUTH")
|
|
}
|
|
|
|
func (ceh *ControllerErrorHandler) HandleNotFoundError(c *fiber.Ctx, resource string) error {
|
|
err := fmt.Errorf("%s not found", resource)
|
|
return ceh.HandleError(c, err, fiber.StatusNotFound, "NOT_FOUND")
|
|
}
|
|
|
|
func (ceh *ControllerErrorHandler) HandleBusinessLogicError(c *fiber.Ctx, err error) error {
|
|
return ceh.HandleError(c, err, fiber.StatusBadRequest, "BUSINESS_LOGIC")
|
|
}
|
|
|
|
func (ceh *ControllerErrorHandler) HandleServiceError(c *fiber.Ctx, err error) error {
|
|
return ceh.HandleError(c, err, fiber.StatusInternalServerError, "SERVICE")
|
|
}
|
|
|
|
func (ceh *ControllerErrorHandler) HandleParsingError(c *fiber.Ctx, err error) error {
|
|
return ceh.HandleError(c, err, fiber.StatusBadRequest, "PARSING")
|
|
}
|
|
|
|
func (ceh *ControllerErrorHandler) HandleUUIDError(c *fiber.Ctx, field string) error {
|
|
err := fmt.Errorf("invalid %s format", field)
|
|
return ceh.HandleError(c, err, fiber.StatusBadRequest, "UUID_VALIDATION", field)
|
|
}
|
|
|
|
var globalErrorHandler *ControllerErrorHandler
|
|
|
|
func GetControllerErrorHandler() *ControllerErrorHandler {
|
|
if globalErrorHandler == nil {
|
|
globalErrorHandler = NewControllerErrorHandler()
|
|
}
|
|
return globalErrorHandler
|
|
}
|
|
|
|
func HandleError(c *fiber.Ctx, err error, statusCode int, context ...string) error {
|
|
return GetControllerErrorHandler().HandleError(c, err, statusCode, context...)
|
|
}
|
|
|
|
func HandleValidationError(c *fiber.Ctx, err error, field string) error {
|
|
return GetControllerErrorHandler().HandleValidationError(c, err, field)
|
|
}
|
|
|
|
func HandleDatabaseError(c *fiber.Ctx, err error) error {
|
|
return GetControllerErrorHandler().HandleDatabaseError(c, err)
|
|
}
|
|
|
|
func HandleAuthError(c *fiber.Ctx, err error) error {
|
|
return GetControllerErrorHandler().HandleAuthError(c, err)
|
|
}
|
|
|
|
func HandleNotFoundError(c *fiber.Ctx, resource string) error {
|
|
return GetControllerErrorHandler().HandleNotFoundError(c, resource)
|
|
}
|
|
|
|
func HandleBusinessLogicError(c *fiber.Ctx, err error) error {
|
|
return GetControllerErrorHandler().HandleBusinessLogicError(c, err)
|
|
}
|
|
|
|
func HandleServiceError(c *fiber.Ctx, err error) error {
|
|
return GetControllerErrorHandler().HandleServiceError(c, err)
|
|
}
|
|
|
|
func HandleParsingError(c *fiber.Ctx, err error) error {
|
|
return GetControllerErrorHandler().HandleParsingError(c, err)
|
|
}
|
|
|
|
func HandleUUIDError(c *fiber.Ctx, field string) error {
|
|
return GetControllerErrorHandler().HandleUUIDError(c, field)
|
|
}
|