package response import ( errors "api.qobiltu.id/apperror" "api.qobiltu.id/models" goErrors "errors" "fmt" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" "net/http" ) type ErrorResponse struct { Details string `json:"details"` ValidationErrors []ValidationError `json:"validation_errors,omitempty"` models.Exception } type API struct { Status string `json:"status"` Message string `json:"message,omitempty"` Data any `json:"data,omitempty"` MetaData any `json:"meta_data"` Error *ErrorResponse `json:"errors,omitempty"` } type List struct { List any `json:"list"` } type ValidationError struct { Field string `json:"field"` Message string `json:"message"` } func HandleError(c *gin.Context, err error) { apiResponse := API{ Status: "error", Message: "An error occurred, " + err.Error(), Error: &ErrorResponse{ Exception: models.Exception{Message: ""}, }, MetaData: struct{}{}, } var appErr *errors.AppError if goErrors.As(err, &appErr) { apiResponse.Error.Details = fmt.Sprintf("%v", appErr.Err) switch specificErr := appErr.Err.(type) { case errors.ValidationError: validationError := make([]ValidationError, len(specificErr.Errors)) apiResponse.Message = "Validation Error" apiResponse.Error.ValidationErrors = validationError for i, ve := range specificErr.Errors { apiResponse.Error.ValidationErrors[i] = ValidationError{ Field: ve.Field, Message: ve.Message, } } c.JSON(http.StatusBadRequest, apiResponse) return case errors.ConflictError: apiResponse.Message = specificErr.Message apiResponse.Error.Details = specificErr.Error() apiResponse.Error.Exception.DataDuplicate = true c.JSON(http.StatusConflict, apiResponse) return case errors.InternalError: apiResponse.Message = specificErr.Message apiResponse.Error.Details = specificErr.Error() apiResponse.Error.Exception.InternalServerError = true c.JSON(http.StatusInternalServerError, apiResponse) return case errors.NotFoundError: apiResponse.Message = specificErr.Message apiResponse.Error.Details = specificErr.Error() apiResponse.Error.Exception.DataNotFound = true c.JSON(http.StatusNotFound, apiResponse) return case errors.UnauthorizedError: apiResponse.Message = specificErr.Message apiResponse.Error.Details = specificErr.Error() apiResponse.Error.Exception.Unauthorized = true c.JSON(http.StatusUnauthorized, apiResponse) return case errors.ForbiddenError: apiResponse.Message = specificErr.Message apiResponse.Error.Details = specificErr.Error() apiResponse.Error.Exception.Forbidden = true c.JSON(http.StatusForbidden, apiResponse) return case errors.BadRequestError: apiResponse.Message = specificErr.Message apiResponse.Error.Details = specificErr.Error() apiResponse.Error.Exception.BadRequest = true c.JSON(http.StatusBadRequest, apiResponse) return default: apiResponse.Error.Details = "An unexpected error occurred." apiResponse.Error.Exception.InternalServerError = true c.JSON(http.StatusInternalServerError, apiResponse) return } } else if validationErrors, ok := err.(validator.ValidationErrors); ok { apiResponse.Error.Details = "Validation failed for the request." apiResponse.Error.Exception.ValidationError = true apiResponse.Error.ValidationErrors = make([]ValidationError, len(validationErrors)) for i, fe := range validationErrors { apiResponse.Error.ValidationErrors[i] = ValidationError{ Field: fe.Field(), Message: fe.Translate(nil), // adjust if you use translator } } c.JSON(http.StatusBadRequest, apiResponse) return } c.JSON(http.StatusInternalServerError, apiResponse) apiResponse.Error.Details = err.Error() } func HandleSuccess(c *gin.Context, message string, statusCode int, data any, metaData any) { apiResponse := API{ Status: "success", Message: message, Data: data, MetaData: metaData, } if metaData == nil { apiResponse.MetaData = struct{}{} } c.JSON(statusCode, apiResponse) } func HandleSuccessWithPaging(c *gin.Context, message string, content any, pagingInfo *PagingInfo) { apiResponse := API{ Message: message, Status: "success", Data: List{ List: content, }, MetaData: pagingInfo, } c.JSON(http.StatusOK, apiResponse) }