Ver Fonte

refactor(nginx): simplify control error handling

Jacky há 9 horas atrás
pai
commit
58f5d6d132

+ 8 - 33
api/nginx/control.go

@@ -9,34 +9,12 @@ import (
 
 // Reload reloads the nginx
 func Reload(c *gin.Context) {
-	output, err := nginx.Reload()
-	if err != nil {
-		c.JSON(http.StatusInternalServerError, gin.H{
-			"message": output + err.Error(),
-			"level":   nginx.GetLogLevel(output),
-		})
-		return
-	}
-	c.JSON(http.StatusOK, gin.H{
-		"message": output,
-		"level":   nginx.GetLogLevel(output),
-	})
+	nginx.Control(nginx.Reload).Resp(c)
 }
 
 // TestConfig tests the nginx config
 func TestConfig(c *gin.Context) {
-	output, err := nginx.TestConfig()
-	if err != nil {
-		c.JSON(http.StatusInternalServerError, gin.H{
-			"message": output + err.Error(),
-			"level":   nginx.GetLogLevel(output),
-		})
-		return
-	}
-	c.JSON(http.StatusOK, gin.H{
-		"message": output,
-		"level":   nginx.GetLogLevel(output),
-	})
+	nginx.Control(nginx.TestConfig).Resp(c)
 }
 
 // Restart restarts the nginx
@@ -49,20 +27,17 @@ func Restart(c *gin.Context) {
 
 // Status returns the status of the nginx
 func Status(c *gin.Context) {
-	lastOutput, err := nginx.GetLastOutput()
-	if err != nil {
-		c.JSON(http.StatusInternalServerError, gin.H{
-			"message": lastOutput + err.Error(),
-			"level":   nginx.GetLogLevel(lastOutput),
-		})
+	lastResult := nginx.GetLastResult()
+	if lastResult.IsError() {
+		lastResult.RespError(c)
 		return
 	}
 
-	running := nginx.IsNginxRunning()
+	running := nginx.IsRunning()
 
 	c.JSON(http.StatusOK, gin.H{
 		"running": running,
-		"message": lastOutput,
-		"level":   nginx.GetLogLevel(lastOutput),
+		"message": lastResult.GetOutput(),
+		"level":   lastResult.GetLevel(),
 	})
 }

+ 62 - 0
internal/nginx/control.go

@@ -0,0 +1,62 @@
+package nginx
+
+import (
+	"errors"
+	"net/http"
+	"strings"
+
+	"github.com/gin-gonic/gin"
+	"github.com/uozi-tech/cosy"
+)
+
+type ControlFunc func() (stdOut string, stdErr error)
+
+type ControlResult struct {
+	stdOut string
+	stdErr error
+}
+
+type ControlResp struct {
+	Message string `json:"message"`
+	Level   int    `json:"level"`
+}
+
+func Control(controlFunc ControlFunc) *ControlResult {
+	stdout, stderr := controlFunc()
+	return &ControlResult{
+		stdOut: stdout,
+		stdErr: stderr,
+	}
+}
+
+func (t *ControlResult) IsError() bool {
+	return GetLogLevel(t.stdOut) > Warn || t.stdErr != nil
+}
+
+func (t *ControlResult) Resp(c *gin.Context) {
+	if t.IsError() {
+		t.RespError(c)
+		return
+	}
+	c.JSON(http.StatusOK, ControlResp{
+		Message: t.stdOut,
+		Level:   GetLogLevel(t.stdOut),
+	})
+}
+
+func (t *ControlResult) RespError(c *gin.Context) {
+	cosy.ErrHandler(c,
+		cosy.WrapErrorWithParams(ErrNginx, strings.Join([]string{t.stdOut, t.stdErr.Error()}, " ")))
+}
+
+func (t *ControlResult) GetOutput() string {
+	return strings.Join([]string{t.stdOut, t.stdErr.Error()}, " ")
+}
+
+func (t *ControlResult) GetError() error {
+	return errors.New(t.GetOutput())
+}
+
+func (t *ControlResult) GetLevel() int {
+	return GetLogLevel(t.stdOut)
+}

+ 3 - 2
internal/nginx/errors.go

@@ -3,7 +3,8 @@ package nginx
 import "github.com/uozi-tech/cosy"
 
 var (
-	e             = cosy.NewErrorScope("nginx")
-	ErrBlockIsNil = e.New(50001, "block is nil")
+	e               = cosy.NewErrorScope("nginx")
+	ErrNginx        = e.New(50000, "nginx error: {0}")
+	ErrBlockIsNil   = e.New(50001, "block is nil")
 	ErrReloadFailed = e.New(50002, "reload nginx failed: {0}")
 )

+ 2 - 2
internal/nginx/modules.go

@@ -51,7 +51,7 @@ func isPIDFileChanged() bool {
 	}
 
 	// If Nginx is not running, consider PID changed
-	if !IsNginxRunning() {
+	if !IsRunning() {
 		return true
 	}
 
@@ -101,7 +101,7 @@ func updateDynamicModulesStatus() {
 	// Look for lines like "load_module modules/ngx_http_image_filter_module.so;"
 	loadModuleRe := regexp.MustCompile(`load_module\s+(?:modules/|/.*/)([a-zA-Z0-9_-]+)\.so;`)
 	matches := loadModuleRe.FindAllStringSubmatch(out, -1)
-	
+
 	for _, match := range matches {
 		if len(match) > 1 {
 			// Extract the module name without path and suffix

+ 6 - 3
internal/nginx/nginx.go

@@ -72,13 +72,16 @@ func Restart() {
 }
 
 // GetLastOutput returns the last output of the nginx command
-func GetLastOutput() (stdOut string, stdErr error) {
+func GetLastResult() *ControlResult {
 	mutex.Lock()
 	defer mutex.Unlock()
-	return lastStdOut, lastStdErr
+	return &ControlResult{
+		stdOut: lastStdOut,
+		stdErr: lastStdErr,
+	}
 }
 
-func IsNginxRunning() bool {
+func IsRunning() bool {
 	pidPath := GetPIDPath()
 	switch settings.NginxSettings.RunningInAnotherContainer() {
 	case true:

+ 1 - 1
internal/performance/performance.go

@@ -19,7 +19,7 @@ type NginxPerformanceResponse struct {
 
 func GetPerformanceData() NginxPerformanceResponse {
 	// Check if Nginx is running
-	running := nginx.IsNginxRunning()
+	running := nginx.IsRunning()
 	if !running {
 		return NginxPerformanceResponse{
 			StubStatusEnabled: false,

+ 4 - 4
mcp/nginx/restart.go

@@ -16,9 +16,9 @@ var nginxRestartTool = mcp.NewTool(
 
 func handleNginxRestart(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
 	nginx.Restart()
-	output, err := nginx.GetLastOutput()
-	if err != nil {
-		return mcp.NewToolResultError(output + "\n" + err.Error()), err
+	lastResult := nginx.GetLastResult()
+	if lastResult.IsError() {
+		return mcp.NewToolResultError(lastResult.GetOutput()), lastResult.GetError()
 	}
-	return mcp.NewToolResultText(output), nil
+	return mcp.NewToolResultText(lastResult.GetOutput()), nil
 }

+ 6 - 10
mcp/nginx/status.go

@@ -19,19 +19,15 @@ var statusTool = mcp.NewTool(
 
 // handleNginxStatus handles the Nginx status request
 func handleNginxStatus(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
-	lastOutput, err := nginx.GetLastOutput()
-	if err != nil {
-		return mcp.NewToolResultError(lastOutput + "\n" + err.Error()), err
+	lastResult := nginx.GetLastResult()
+	if lastResult.IsError() {
+		return mcp.NewToolResultError(lastResult.GetOutput()), lastResult.GetError()
 	}
-
-	running := nginx.IsNginxRunning()
-	level := nginx.GetLogLevel(lastOutput)
-
 	// build result
 	result := gin.H{
-		"running": running,
-		"message": lastOutput,
-		"level":   level,
+		"running": nginx.IsRunning(),
+		"message": lastResult.GetOutput(),
+		"level":   lastResult.GetLevel(),
 	}
 
 	// marshal to json and return text result