From ec658e4fa7fefe118e6ce4e883ca0ebb1295e9f4 Mon Sep 17 00:00:00 2001 From: Abhishek Shroff Date: Sat, 10 Aug 2024 22:22:22 +0530 Subject: [PATCH] [server] Add json body to 500s and descriptions to all errors --- server/internal/api/errors/errors.go | 8 ++++---- server/internal/api/routes/auth.go | 6 +++--- server/internal/api/routes/mobile.go | 3 +-- server/internal/api/routes/resources.go | 22 ++++++++++++---------- server/internal/command/appcmd/serve.go | 9 ++++++++- 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/server/internal/api/errors/errors.go b/server/internal/api/errors/errors.go index 15f35db1..f61b39ff 100644 --- a/server/internal/api/errors/errors.go +++ b/server/internal/api/errors/errors.go @@ -10,19 +10,19 @@ import ( type ApiErr struct { Status int `json:"status"` Code string `json:"code"` - Details string `json:"details"` + Message string `json:"msg"` } -func New(httpStatus int, code, details string) error { +func New(httpStatus int, code, msg string) error { return &ApiErr{ Status: httpStatus, Code: code, - Details: details, + Message: msg, } } func (e *ApiErr) Error() string { - return fmt.Sprintf("%d %s (%s)", e.Status, e.Code, e.Details) + return fmt.Sprintf("%d %s (%s)", e.Status, e.Code, e.Message) } func Is(err, target error) bool { diff --git a/server/internal/api/routes/auth.go b/server/internal/api/routes/auth.go index 8798eba0..1a1f13d0 100644 --- a/server/internal/api/routes/auth.go +++ b/server/internal/api/routes/auth.go @@ -22,16 +22,16 @@ func createLoginRouteHandler(a *core.App) func(c *gin.Context) { return func(c *gin.Context) { username, ok := c.GetQuery("username") if !ok { - panic(errors.New(http.StatusBadRequest, "missing_username", "")) + panic(errors.New(http.StatusBadRequest, "missing_username", "Username Not Specified")) } password, ok := c.GetQuery("password") if !ok { - panic(errors.New(http.StatusBadRequest, "missing_password", "")) + panic(errors.New(http.StatusBadRequest, "missing_password", "Password Not Specified")) } if user, err := a.VerifyUserPassword(c.Request.Context(), username, password); err != nil { if errors.Is(err, core.ErrCredentialsInvalid) { - panic(errors.New(http.StatusUnauthorized, "credentials_invalid", "")) + panic(errors.New(http.StatusUnauthorized, "credentials_invalid", "Invalid Credentials")) } panic(err) } else { diff --git a/server/internal/api/routes/mobile.go b/server/internal/api/routes/mobile.go index c6cd3729..088c24d8 100644 --- a/server/internal/api/routes/mobile.go +++ b/server/internal/api/routes/mobile.go @@ -2,7 +2,6 @@ package routes import ( iofs "io/fs" - "net/http" "github.com/gin-gonic/gin" "github.com/shroff/phylum/server/internal/api/auth" @@ -25,7 +24,7 @@ func handleMobileHomeRoute(c *gin.Context) { r, err := fs.ResourceByID(user.Home()) if err != nil { if errors.Is(err, iofs.ErrNotExist) { - err = errors.New(http.StatusNotFound, errCodeResourceNotFound, "") + err = errResourceNotFound } panic(err) } diff --git a/server/internal/api/routes/resources.go b/server/internal/api/routes/resources.go index e855c4b4..fa88a6dd 100644 --- a/server/internal/api/routes/resources.go +++ b/server/internal/api/routes/resources.go @@ -12,9 +12,11 @@ import ( "github.com/shroff/phylum/server/internal/core" ) -const errCodeResourceNotFound = "resource_not_found" -const errCodeResourceIdInvalid = "resource_id_invalid" -const errCodeResourceNotCollection = "resource_not_collection" +var ( + errResourceIdInvalid = errors.New(http.StatusBadRequest, "resource_id_invalid", "Invalid UUID") + errResourceNotFound = errors.New(http.StatusNotFound, "resource_not_found", "Resource Not Found") + errResourceNotDirectory = errors.New(http.StatusMethodNotAllowed, "resource_not_directory", "Resource Not Directory") +) type resourceResponse struct { ID uuid.UUID `json:"id"` @@ -44,14 +46,14 @@ func SetupResourceRoutes(r *gin.RouterGroup) { func handleResourceMetadataRoute(c *gin.Context) { resourceId, err := uuid.Parse(c.Param("id")) if err != nil { - panic(errors.New(http.StatusBadRequest, errCodeResourceIdInvalid, "")) + panic(errResourceIdInvalid) } fs := auth.GetFileSystem(c) resource, err := fs.ResourceByID(resourceId) if err != nil { if errors.Is(err, iofs.ErrNotExist) { - err = errors.New(http.StatusNotFound, errCodeResourceNotFound, "") + err = errResourceNotFound } panic(err) } @@ -62,20 +64,20 @@ func handleResourceMetadataRoute(c *gin.Context) { func handleResourceLsRoute(c *gin.Context) { resourceId, err := uuid.Parse(c.Param("id")) if err != nil { - panic(errors.New(http.StatusBadRequest, errCodeResourceIdInvalid, "")) + panic(errResourceIdInvalid) } fs := auth.GetFileSystem(c) resource, err := fs.ResourceByID(resourceId) if err != nil { if errors.Is(err, iofs.ErrNotExist) { - err = errors.New(http.StatusNotFound, errCodeResourceNotFound, "") + err = errResourceNotFound } panic(err) } if !resource.IsDir() { - panic(errors.New(http.StatusBadRequest, errCodeResourceNotCollection, "")) + panic(errResourceNotDirectory) } children, err := fs.ReadDir(resource) if err != nil { @@ -91,14 +93,14 @@ func handleResourceLsRoute(c *gin.Context) { func handleResourceDetailsRoute(c *gin.Context) { resourceID, err := uuid.Parse(c.Param("id")) if err != nil { - panic(errors.New(http.StatusBadRequest, errCodeResourceIdInvalid, "")) + panic(errResourceIdInvalid) } fs := auth.GetFileSystem(c) r, err := fs.ResourceByID(resourceID) if err != nil { if errors.Is(err, iofs.ErrNotExist) { - err = errors.New(http.StatusNotFound, errCodeResourceNotFound, "") + err = errResourceNotFound } panic(err) } diff --git a/server/internal/command/appcmd/serve.go b/server/internal/command/appcmd/serve.go index 81a659fb..9fd8c929 100644 --- a/server/internal/command/appcmd/serve.go +++ b/server/internal/command/appcmd/serve.go @@ -2,6 +2,7 @@ package appcmd import ( "bytes" + "net/http" "time" "github.com/fvbock/endless" @@ -63,7 +64,13 @@ func createEngine(logBody bool, corsEnabled bool, corsOrigins []string) *gin.Eng if !core.Default.Debug { gin.SetMode(gin.ReleaseMode) } - engine := gin.Default() + engine := gin.New() + engine.Use(gin.Logger(), gin.CustomRecovery(func(c *gin.Context, err any) { + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{ + "code": "internal_server_error", + "msg": "Internal Server Error", + }) + })) if core.Default.Debug && logBody { engine.Use(logBodyMiddleware) }