Skip to content

Commit

Permalink
refactor: change to use generic errors in controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
Yeuoly committed Nov 22, 2024
1 parent 3d3d0fa commit ef1ffa9
Show file tree
Hide file tree
Showing 18 changed files with 289 additions and 147 deletions.
13 changes: 6 additions & 7 deletions internal/server/controllers/base.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package controllers

import (
"errors"

"github.com/gin-gonic/gin"
"github.com/langgenius/dify-plugin-daemon/internal/server/constants"
"github.com/langgenius/dify-plugin-daemon/internal/types/entities"
"github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
"github.com/langgenius/dify-plugin-daemon/internal/types/exception"
"github.com/langgenius/dify-plugin-daemon/internal/types/validators"
)

Expand All @@ -22,8 +24,7 @@ func BindRequest[T any](r *gin.Context, success func(T)) {

// validate, we have customized some validators which are not supported by gin binding
if err := validators.GlobalEntitiesValidator.Struct(request); err != nil {
resp := entities.NewErrorResponse(-400, err.Error())
r.JSON(400, resp)
r.JSON(400, exception.BadRequestError(err).ToResponse())
return
}

Expand All @@ -36,15 +37,13 @@ func BindPluginDispatchRequest[T any](r *gin.Context, success func(
BindRequest(r, func(req plugin_entities.InvokePluginRequest[T]) {
pluginUniqueIdentifierAny, exists := r.Get(constants.CONTEXT_KEY_PLUGIN_UNIQUE_IDENTIFIER)
if !exists {
resp := entities.NewErrorResponse(-400, "Plugin unique identifier is required")
r.JSON(400, resp)
r.JSON(400, exception.PluginUniqueIdentifierError(errors.New("Plugin unique identifier is required")).ToResponse())
return
}

pluginUniqueIdentifier, ok := pluginUniqueIdentifierAny.(plugin_entities.PluginUniqueIdentifier)
if !ok {
resp := entities.NewErrorResponse(-400, "Plugin unique identifier is required")
r.JSON(400, resp)
r.JSON(400, exception.PluginUniqueIdentifierError(errors.New("Plugin unique identifier is not valid")).ToResponse())
return
}

Expand Down
23 changes: 12 additions & 11 deletions internal/server/controllers/plugins.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
package controllers

import (
"errors"
"net/http"
"strings"

"github.com/gin-gonic/gin"
"github.com/langgenius/dify-plugin-daemon/internal/core/plugin_manager"
"github.com/langgenius/dify-plugin-daemon/internal/service"
"github.com/langgenius/dify-plugin-daemon/internal/types/app"
"github.com/langgenius/dify-plugin-daemon/internal/types/entities"
"github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
"github.com/langgenius/dify-plugin-daemon/internal/types/exception"
)

func GetAsset(c *gin.Context) {
pluginManager := plugin_manager.Manager()
asset, err := pluginManager.GetAsset(c.Param("id"))

if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
c.JSON(http.StatusInternalServerError, exception.InternalServerError(err).ToResponse())
return
}

Expand All @@ -28,26 +29,26 @@ func UploadPlugin(app *app.Config) gin.HandlerFunc {
return func(c *gin.Context) {
difyPkgFileHeader, err := c.FormFile("dify_pkg")
if err != nil {
c.JSON(http.StatusOK, entities.NewErrorResponse(-400, err.Error()))
c.JSON(http.StatusOK, exception.BadRequestError(err).ToResponse())
return
}

tenantId := c.Param("tenant_id")
if tenantId == "" {
c.JSON(http.StatusOK, entities.NewErrorResponse(-400, "Tenant ID is required"))
c.JSON(http.StatusOK, exception.BadRequestError(errors.New("Tenant ID is required")).ToResponse())
return
}

if difyPkgFileHeader.Size > app.MaxPluginPackageSize {
c.JSON(http.StatusOK, entities.NewErrorResponse(-413, "File size exceeds the maximum limit"))
c.JSON(http.StatusOK, exception.BadRequestError(errors.New("File size exceeds the maximum limit")).ToResponse())
return
}

verifySignature := c.PostForm("verify_signature") == "true"

difyPkgFile, err := difyPkgFileHeader.Open()
if err != nil {
c.JSON(http.StatusOK, entities.NewErrorResponse(-400, err.Error()))
c.JSON(http.StatusOK, exception.BadRequestError(err).ToResponse())
return
}
defer difyPkgFile.Close()
Expand All @@ -60,26 +61,26 @@ func UploadBundle(app *app.Config) gin.HandlerFunc {
return func(c *gin.Context) {
difyBundleFileHeader, err := c.FormFile("dify_bundle")
if err != nil {
c.JSON(http.StatusOK, entities.NewErrorResponse(-400, err.Error()))
c.JSON(http.StatusOK, exception.BadRequestError(err).ToResponse())
return
}

tenantId := c.Param("tenant_id")
if tenantId == "" {
c.JSON(http.StatusOK, entities.NewErrorResponse(-400, "Tenant ID is required"))
c.JSON(http.StatusOK, exception.BadRequestError(errors.New("Tenant ID is required")).ToResponse())
return
}

if difyBundleFileHeader.Size > app.MaxBundlePackageSize {
c.JSON(http.StatusOK, entities.NewErrorResponse(-413, "File size exceeds the maximum limit"))
c.JSON(http.StatusOK, exception.BadRequestError(errors.New("File size exceeds the maximum limit")).ToResponse())
return
}

verifySignature := c.PostForm("verify_signature") == "true"

difyBundleFile, err := difyBundleFileHeader.Open()
if err != nil {
c.JSON(http.StatusOK, entities.NewErrorResponse(-400, err.Error()))
c.JSON(http.StatusOK, exception.BadRequestError(err).ToResponse())
return
}
defer difyBundleFile.Close()
Expand Down Expand Up @@ -164,7 +165,7 @@ func DeletePluginInstallationItemFromTask(c *gin.Context) {
identifierString := strings.TrimLeft(request.Identifier, "/")
identifier, err := plugin_entities.NewPluginUniqueIdentifier(identifierString)
if err != nil {
c.JSON(http.StatusOK, entities.NewErrorResponse(-400, err.Error()))
c.JSON(http.StatusOK, exception.BadRequestError(err).ToResponse())
return
}

Expand Down
13 changes: 9 additions & 4 deletions internal/server/endpoint.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package server

import (
"errors"

"github.com/gin-gonic/gin"
"github.com/langgenius/dify-plugin-daemon/internal/db"
"github.com/langgenius/dify-plugin-daemon/internal/service"
"github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
"github.com/langgenius/dify-plugin-daemon/internal/types/exception"
"github.com/langgenius/dify-plugin-daemon/internal/types/models"
"github.com/langgenius/dify-plugin-daemon/internal/utils/log"
)
Expand Down Expand Up @@ -34,13 +37,13 @@ func (app *App) EndpointHandler(ctx *gin.Context, hookId string, path string) {
db.Equal("hook_id", hookId),
)
if err == db.ErrDatabaseNotFound {
ctx.JSON(404, gin.H{"error": "endpoint not found"})
ctx.JSON(404, exception.BadRequestError(errors.New("endpoint not found")).ToResponse())
return
}

if err != nil {
log.Error("get endpoint error %v", err)
ctx.JSON(500, gin.H{"error": "internal server error"})
ctx.JSON(500, exception.InternalServerError(errors.New("internal server error")).ToResponse())
return
}

Expand All @@ -50,15 +53,17 @@ func (app *App) EndpointHandler(ctx *gin.Context, hookId string, path string) {
db.Equal("tenant_id", endpoint.TenantID),
)
if err != nil {
ctx.JSON(404, gin.H{"error": "plugin installation not found"})
ctx.JSON(404, exception.BadRequestError(errors.New("plugin installation not found")).ToResponse())
return
}

pluginUniqueIdentifier, err := plugin_entities.NewPluginUniqueIdentifier(
pluginInstallation.PluginUniqueIdentifier,
)
if err != nil {
ctx.JSON(400, gin.H{"error": "invalid plugin unique identifier"})
ctx.JSON(400, exception.PluginUniqueIdentifierError(
errors.New("invalid plugin unique identifier"),
).ToResponse())
return
}

Expand Down
42 changes: 31 additions & 11 deletions internal/server/middleware.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package server

import (
"errors"
"io"

"github.com/gin-gonic/gin"
"github.com/langgenius/dify-plugin-daemon/internal/db"
"github.com/langgenius/dify-plugin-daemon/internal/server/constants"
"github.com/langgenius/dify-plugin-daemon/internal/types/entities"
"github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
"github.com/langgenius/dify-plugin-daemon/internal/types/exception"
"github.com/langgenius/dify-plugin-daemon/internal/types/models"
"github.com/langgenius/dify-plugin-daemon/internal/utils/log"
)
Expand All @@ -16,7 +17,7 @@ func CheckingKey(key string) gin.HandlerFunc {
return func(c *gin.Context) {
// get header X-Api-Key
if c.GetHeader(constants.X_API_KEY) != key {
c.JSON(200, entities.NewErrorResponse(-401, "Unauthorized"))
c.JSON(200, exception.UnauthorizedError().ToResponse())
c.Abort()
return
}
Expand All @@ -29,13 +30,13 @@ func (app *App) FetchPluginInstallation() gin.HandlerFunc {
return func(ctx *gin.Context) {
pluginId := ctx.Request.Header.Get(constants.X_PLUGIN_ID)
if pluginId == "" {
ctx.AbortWithStatusJSON(400, gin.H{"error": "Invalid request, plugin_id is required"})
ctx.AbortWithStatusJSON(400, exception.BadRequestError(errors.New("plugin_id is required")).ToResponse())
return
}

tenantId := ctx.Param("tenant_id")
if tenantId == "" {
ctx.AbortWithStatusJSON(400, gin.H{"error": "Invalid request, tenant_id is required"})
ctx.AbortWithStatusJSON(400, exception.BadRequestError(errors.New("tenant_id is required")).ToResponse())
return
}

Expand All @@ -44,14 +45,20 @@ func (app *App) FetchPluginInstallation() gin.HandlerFunc {
db.Equal("tenant_id", tenantId),
db.Equal("plugin_id", pluginId),
)

if err == db.ErrDatabaseNotFound {
ctx.AbortWithStatusJSON(404, exception.ErrPluginNotFound().ToResponse())
return
}

if err != nil {
ctx.AbortWithStatusJSON(400, gin.H{"error": "Invalid request, " + err.Error()})
ctx.AbortWithStatusJSON(500, exception.InternalServerError(err).ToResponse())
return
}

identity, err := plugin_entities.NewPluginUniqueIdentifier(installation.PluginUniqueIdentifier)
if err != nil {
ctx.AbortWithStatusJSON(400, gin.H{"error": "Invalid request, " + err.Error()})
ctx.AbortWithStatusJSON(400, exception.PluginUniqueIdentifierError(err).ToResponse())
return
}

Expand All @@ -67,13 +74,19 @@ func (app *App) RedirectPluginInvoke() gin.HandlerFunc {
// get plugin unique identifier
identityAny, ok := ctx.Get(constants.CONTEXT_KEY_PLUGIN_UNIQUE_IDENTIFIER)
if !ok {
ctx.AbortWithStatusJSON(500, gin.H{"error": "Internal server error, plugin unique identifier not found"})
ctx.AbortWithStatusJSON(
500,
exception.InternalServerError(errors.New("plugin unique identifier not found")).ToResponse(),
)
return
}

identity, ok := identityAny.(plugin_entities.PluginUniqueIdentifier)
if !ok {
ctx.AbortWithStatusJSON(500, gin.H{"error": "Internal server error, failed to parse plugin unique identifier"})
ctx.AbortWithStatusJSON(
500,
exception.InternalServerError(errors.New("failed to parse plugin unique identifier")).ToResponse(),
)
return
}

Expand All @@ -97,13 +110,17 @@ func (app *App) redirectPluginInvokeByPluginIdentifier(
if err != nil {
ctx.AbortWithStatusJSON(
500,
gin.H{"error": "Internal server error, " + originalError.Error() + ", " + err.Error()},
exception.InternalServerError(
errors.New("failed to fetch plugin available nodes, "+originalError.Error()+", "+err.Error()),
).ToResponse(),
)
return
} else if len(nodes) == 0 {
ctx.AbortWithStatusJSON(
404,
gin.H{"error": "No available node, " + originalError.Error()},
exception.InternalServerError(
errors.New("no available node, "+originalError.Error()),
).ToResponse(),
)
return
}
Expand All @@ -113,7 +130,10 @@ func (app *App) redirectPluginInvokeByPluginIdentifier(
statusCode, header, body, err := app.cluster.RedirectRequest(nodeId, ctx.Request)
if err != nil {
log.Error("redirect request failed: %s", err.Error())
ctx.AbortWithStatusJSON(500, gin.H{"error": "Internal server error"})
ctx.AbortWithStatusJSON(
500,
exception.InternalServerError(errors.New("redirect request failed: "+err.Error())).ToResponse(),
)
return
}

Expand Down
8 changes: 5 additions & 3 deletions internal/service/base_sse.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package service

import (
"errors"
"sync/atomic"
"time"

"github.com/gin-gonic/gin"
"github.com/langgenius/dify-plugin-daemon/internal/types/entities"
"github.com/langgenius/dify-plugin-daemon/internal/types/exception"
"github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
"github.com/langgenius/dify-plugin-daemon/internal/utils/routine"
"github.com/langgenius/dify-plugin-daemon/internal/utils/stream"
Expand Down Expand Up @@ -39,7 +41,7 @@ func baseSSEService[R any](
pluginDaemonResponse, err := generator()

if err != nil {
writeData(entities.NewErrorResponse(-500, err.Error()))
writeData(exception.InternalServerError(err).ToResponse())
close(done)
return
}
Expand All @@ -48,7 +50,7 @@ func baseSSEService[R any](
for pluginDaemonResponse.Next() {
chunk, err := pluginDaemonResponse.Read()
if err != nil {
writeData(entities.NewErrorResponse(-500, err.Error()))
writeData(exception.InternalServerError(err).ToResponse())
break
}
writeData(entities.NewSuccessResponse(chunk))
Expand All @@ -73,7 +75,7 @@ func baseSSEService[R any](
case <-done:
return
case <-timer.C:
writeData(entities.NewErrorResponse(-500, "killed by timeout"))
writeData(exception.InternalServerError(errors.New("killed by timeout")).ToResponse())
if atomic.CompareAndSwapInt32(doneClosed, 0, 1) {
close(done)
}
Expand Down
7 changes: 4 additions & 3 deletions internal/service/debugging.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package service
import (
"github.com/langgenius/dify-plugin-daemon/internal/core/plugin_manager/remote_manager"
"github.com/langgenius/dify-plugin-daemon/internal/types/entities"
"github.com/langgenius/dify-plugin-daemon/internal/types/exception"
)

func GetRemoteDebuggingKey(tenant_id string) entities.Response {
func GetRemoteDebuggingKey(tenant_id string) *entities.Response {
type response struct {
Key string `json:"key"`
}
Expand All @@ -15,10 +16,10 @@ func GetRemoteDebuggingKey(tenant_id string) entities.Response {
})

if err != nil {
return *entities.NewErrorResponse(-500, err.Error())
return exception.InternalServerError(err).ToResponse()
}

return *entities.NewSuccessResponse(response{
return entities.NewSuccessResponse(response{
Key: key,
})
}
Loading

0 comments on commit ef1ffa9

Please sign in to comment.