WIP: Better error handling

This commit is contained in:
rxdn 2024-11-11 23:19:54 +00:00
parent 4c405bfd73
commit e39d73f2da
4 changed files with 76 additions and 15 deletions

29
app/errors.go Normal file
View File

@ -0,0 +1,29 @@
package app
import "fmt"
type ApiError struct {
InternalError error
ExternalMessage string
}
var _ error = (*ApiError)(nil)
func NewError(internalError error, externalMessage string) *ApiError {
return &ApiError{
InternalError: internalError,
ExternalMessage: externalMessage,
}
}
func NewServerError(internalError error) *ApiError {
return NewError(internalError, "An internal server error occurred")
}
func (e *ApiError) Error() string {
return fmt.Sprintf("internal error: %v, external message: %s", e.InternalError, e.ExternalMessage)
}
func (e *ApiError) Unwrap() error {
return e.InternalError
}

View File

@ -2,16 +2,17 @@ package api
import ( import (
"context" "context"
"github.com/TicketsBot/GoPanel/app"
dbclient "github.com/TicketsBot/GoPanel/database" dbclient "github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/GoPanel/utils/types" "github.com/TicketsBot/GoPanel/utils/types"
"github.com/TicketsBot/database" "github.com/TicketsBot/database"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"net/http"
"strconv" "strconv"
) )
func ListPanels(ctx *gin.Context) { func ListPanels(c *gin.Context) {
type panelResponse struct { type panelResponse struct {
database.Panel database.Panel
WelcomeMessage *types.CustomEmbed `json:"welcome_message"` WelcomeMessage *types.CustomEmbed `json:"welcome_message"`
@ -23,23 +24,23 @@ func ListPanels(ctx *gin.Context) {
AccessControlList []database.PanelAccessControlRule `json:"access_control_list"` AccessControlList []database.PanelAccessControlRule `json:"access_control_list"`
} }
guildId := ctx.Keys["guildid"].(uint64) guildId := c.Keys["guildid"].(uint64)
panels, err := dbclient.Client.Panel.GetByGuildWithWelcomeMessage(ctx, guildId) panels, err := dbclient.Client.Panel.GetByGuildWithWelcomeMessage(c, guildId)
if err != nil { if err != nil {
ctx.JSON(500, utils.ErrorJson(err)) _ = c.AbortWithError(http.StatusInternalServerError, app.NewServerError(err))
return return
} }
accessControlLists, err := dbclient.Client.PanelAccessControlRules.GetAllForGuild(ctx, guildId) accessControlLists, err := dbclient.Client.PanelAccessControlRules.GetAllForGuild(c, guildId)
if err != nil { if err != nil {
ctx.JSON(500, utils.ErrorJson(err)) _ = c.AbortWithError(http.StatusInternalServerError, app.NewServerError(err))
return return
} }
allFields, err := dbclient.Client.EmbedFields.GetAllFieldsForPanels(ctx, guildId) allFields, err := dbclient.Client.EmbedFields.GetAllFieldsForPanels(c, guildId)
if err != nil { if err != nil {
ctx.JSON(500, utils.ErrorJson(err)) _ = c.AbortWithError(http.StatusInternalServerError, app.NewServerError(err))
return return
} }
@ -56,7 +57,7 @@ func ListPanels(ctx *gin.Context) {
var mentions []string var mentions []string
// get if we should mention the ticket opener // get if we should mention the ticket opener
shouldMention, err := dbclient.Client.PanelUserMention.ShouldMentionUser(ctx, p.PanelId) shouldMention, err := dbclient.Client.PanelUserMention.ShouldMentionUser(c, p.PanelId)
if err != nil { if err != nil {
return err return err
} }
@ -66,7 +67,7 @@ func ListPanels(ctx *gin.Context) {
} }
// get role mentions // get role mentions
roles, err := dbclient.Client.PanelRoleMentions.GetRoles(ctx, p.PanelId) roles, err := dbclient.Client.PanelRoleMentions.GetRoles(c, p.PanelId)
if err != nil { if err != nil {
return err return err
} }
@ -76,7 +77,7 @@ func ListPanels(ctx *gin.Context) {
mentions = append(mentions, strconv.FormatUint(roleId, 10)) mentions = append(mentions, strconv.FormatUint(roleId, 10))
} }
teamIds, err := dbclient.Client.PanelTeams.GetTeamIds(ctx, p.PanelId) teamIds, err := dbclient.Client.PanelTeams.GetTeamIds(c, p.PanelId)
if err != nil { if err != nil {
return err return err
} }
@ -113,9 +114,9 @@ func ListPanels(ctx *gin.Context) {
} }
if err := group.Wait(); err != nil { if err := group.Wait(); err != nil {
ctx.JSON(500, utils.ErrorJson(err)) _ = c.AbortWithError(http.StatusInternalServerError, app.NewServerError(err))
return return
} }
ctx.JSON(200, wrapped) c.JSON(200, wrapped)
} }

View File

@ -0,0 +1,30 @@
package middleware
import (
"errors"
"github.com/TicketsBot/GoPanel/app"
"github.com/gin-gonic/gin"
)
type ErrorResponse struct {
Error string `json:"error"`
}
func ErrorHandler(c *gin.Context) {
c.Next()
if len(c.Errors) > 0 {
var message string
var apiError *app.ApiError
if errors.As(c.Errors[0], &apiError) {
message = apiError.ExternalMessage
} else {
message = "An error occurred processing your request"
}
c.JSON(-1, ErrorResponse{
Error: message,
})
}
}

View File

@ -33,6 +33,7 @@ func StartServer(logger *zap.Logger, sm *livechat.SocketManager) {
router := gin.New() router := gin.New()
router.Use(gin.Recovery()) router.Use(gin.Recovery())
router.Use(middleware.Logging(logger)) router.Use(middleware.Logging(logger))
router.Use(middleware.ErrorHandler)
router.RemoteIPHeaders = config.Conf.Server.RealIpHeaders router.RemoteIPHeaders = config.Conf.Server.RealIpHeaders
if err := router.SetTrustedProxies(config.Conf.Server.TrustedProxies); err != nil { if err := router.SetTrustedProxies(config.Conf.Server.TrustedProxies); err != nil {