diff --git a/scnserver/api/apierr/enums.go b/scnserver/api/apierr/enums.go index d73179f..4f5d47e 100644 --- a/scnserver/api/apierr/enums.go +++ b/scnserver/api/apierr/enums.go @@ -54,4 +54,6 @@ const ( FIREBASE_COM_FAILED APIError = 9901 FIREBASE_COM_ERRORED APIError = 9902 INTERNAL_EXCEPTION APIError = 9903 + PANIC APIError = 9904 + NOT_IMPLEMENTED APIError = 9905 ) diff --git a/scnserver/api/ginresp/resp.go b/scnserver/api/ginresp/resp.go index 56955f4..1446e26 100644 --- a/scnserver/api/ginresp/resp.go +++ b/scnserver/api/ginresp/resp.go @@ -91,7 +91,7 @@ func SendAPIError(g *gin.Context, status int, errorid apierr.APIError, highlight } func NotImplemented(g *gin.Context) HTTPResponse { - return createApiError(g, "NotImplemented", 500, apierr.UNDEFINED, 0, "Not Implemented", nil) + return createApiError(g, "NotImplemented", 500, apierr.NOT_IMPLEMENTED, 0, "Not Implemented", nil) } func createApiError(g *gin.Context, ident string, status int, errorid apierr.APIError, highlight apihighlight.ErrHighlight, msg string, e error) HTTPResponse { diff --git a/scnserver/api/ginresp/wrapper.go b/scnserver/api/ginresp/wrapper.go index 0089c77..6ab249a 100644 --- a/scnserver/api/ginresp/wrapper.go +++ b/scnserver/api/ginresp/wrapper.go @@ -2,6 +2,9 @@ package ginresp import ( scn "blackforestbytes.com/simplecloudnotifier" + "blackforestbytes.com/simplecloudnotifier/api/apierr" + "errors" + "fmt" "github.com/gin-gonic/gin" "github.com/mattn/go-sqlite3" "github.com/rs/zerolog/log" @@ -26,7 +29,11 @@ func Wrap(fn WHandlerFunc) gin.HandlerFunc { for ctr := 1; ; ctr++ { - wrap := fn(g) + wrap, panicObj := callPanicSafe(fn, g) + if panicObj != nil { + log.Error().Interface("panicObj", panicObj).Msg("Panic occured (in gin handler)") + wrap = APIError(g, 500, apierr.PANIC, "A panic occured in the HTTP handler", errors.New(fmt.Sprintf("%+v", panicObj))) + } if g.Writer.Written() { panic("Writing in WrapperFunc is not supported") @@ -55,6 +62,18 @@ func Wrap(fn WHandlerFunc) gin.HandlerFunc { } +func callPanicSafe(fn WHandlerFunc, g *gin.Context) (res HTTPResponse, panicObj any) { + defer func() { + if rec := recover(); rec != nil { + res = nil + panicObj = rec + } + }() + + res = fn(g) + return res, nil +} + func resetBody(g *gin.Context) error { if g.Request.Body == nil { return nil