package utils import ( "errors" dto "whatsapp-backend/models/dto" http_error "whatsapp-backend/models/error" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" "gorm.io/gorm" ) func ResponseOK[Tdata any, TMetaData any](c *gin.Context, metaData TMetaData, data Tdata) { c.JSON(200, dto.SuccessResponse[Tdata]{ Status: "success", Data: data, Message: "Data retrieved Successfully!", MetaData: metaData, }) } func ResponseFAILED[TMetaData any](c *gin.Context, metaData TMetaData, err error) { if errors.Is(err, http_error.BAD_REQUEST_ERROR) { c.JSON(400, dto.ErrorResponse{ Status: "error", Error: err, Message: "Invalid request format!", MetaData: metaData, }) return } else if errors.Is(err, http_error.INTERNAL_SERVER_ERROR) { c.JSON(500, dto.ErrorResponse{ Status: "error", Error: err, Message: "Internal Server Error!", MetaData: metaData, }) return } else if errors.Is(err, http_error.UNAUTHORIZED) { c.JSON(401, dto.ErrorResponse{ Status: "error", Error: err, Message: "Unauthorized, you don't have permission to access this service!", MetaData: metaData, }) return } else if errors.Is(err, http_error.DATA_NOT_FOUND) || errors.Is(err, gorm.ErrRecordNotFound) { c.JSON(404, dto.ErrorResponse{ Status: "error", Error: err, Message: "There is not data with given credential / given parameter!", MetaData: metaData, }) return } else if errors.Is(err, http_error.TIMEOUT) { c.JSON(504, dto.ErrorResponse{ Status: "error", Error: err, Message: "Server took to long to respond!", MetaData: metaData, }) return } else if errors.Is(err, http_error.FORBIDDEN) || errors.Is(err, http_error.ERR_INVALID_CSRF) { c.JSON(403, dto.ErrorResponse{ Status: "error", Error: err, Message: "Forbidden action!", MetaData: metaData, }) return } else { // Check for Validation Errors var validationErrors validator.ValidationErrors if errors.As(err, &validationErrors) { friendlyErrors := make([]string, len(validationErrors)) for i, fieldError := range validationErrors { friendlyErrors[i] = msgForTag(fieldError) } c.JSON(400, dto.ErrorResponse{ Status: "error", Error: friendlyErrors, Message: "Validation Failed", MetaData: nil, }) return } if errors.Is(err, http_error.ERR_USER_NOT_FOUND) || errors.Is(err, http_error.ERR_WRONG_PASSWORD) { c.JSON(401, dto.ErrorResponse{ Status: "error", Error: err, Message: err.Error(), MetaData: metaData, }) return } else if errors.Is(err, http_error.ERR_USER_ALREADY_EXISTS) { c.JSON(409, dto.ErrorResponse{ Status: "error", Error: err, Message: err.Error(), MetaData: metaData, }) return } // Default to 500 c.JSON(500, dto.ErrorResponse{ Status: "error", Error: err, Message: err.Error(), MetaData: metaData, }) return } } func SendResponse[Tdata any, TMetaData any](c *gin.Context, metaData TMetaData, data Tdata, err error) { if !c.IsAborted() { if err != nil { ResponseFAILED(c, metaData, err) c.Abort() return } else { ResponseOK(c, metaData, data) c.Abort() return } } } func msgForTag(fe validator.FieldError) string { switch fe.Tag() { case "required": return "This field is required" case "email": return "Invalid email format" case "min": return fe.Field() + " must be longer than " + fe.Param() + " characters" case "max": return fe.Field() + " must be shorter than " + fe.Param() + " characters" } return fe.Error() // Default error message }