From 7c1b4b70c4adc47d1c52f969c88804b60e668a44 Mon Sep 17 00:00:00 2001 From: pycook Date: Sun, 3 Aug 2025 21:39:52 +0800 Subject: [PATCH] feat(backend): replace JSON errors with user-friendly HTML error pages and reduce log noise --- backend/internal/api/controller/web_proxy.go | 30 +++- backend/internal/api/middleware/logger.go | 24 ++- backend/internal/service/web_proxy/content.go | 153 +++++++++++++++++- backend/internal/service/web_proxy/service.go | 14 +- 4 files changed, 199 insertions(+), 22 deletions(-) diff --git a/backend/internal/api/controller/web_proxy.go b/backend/internal/api/controller/web_proxy.go index a616846..06c4e07 100644 --- a/backend/internal/api/controller/web_proxy.go +++ b/backend/internal/api/controller/web_proxy.go @@ -36,6 +36,30 @@ func (c *WebProxyController) renderSessionExpiredPage(ctx *gin.Context, reason s ctx.String(http.StatusUnauthorized, html) } +func (c *WebProxyController) renderErrorPage(ctx *gin.Context, errorType, title, reason, details string) { + html := web_proxy.RenderErrorPage(errorType, title, reason, details) + ctx.Header("Content-Type", "text/html; charset=utf-8") + + // Set appropriate HTTP status code based on error type + var statusCode int + switch errorType { + case "access_denied": + statusCode = http.StatusForbidden + case "session_expired": + statusCode = http.StatusUnauthorized + case "connection_error": + statusCode = http.StatusBadGateway + case "concurrent_limit": + statusCode = http.StatusTooManyRequests + case "server_error": + statusCode = http.StatusInternalServerError + default: + statusCode = http.StatusInternalServerError + } + + ctx.String(statusCode, html) +} + // GetWebAssetConfig get web asset configuration // @Summary Get web asset configuration // @Description Get web asset configuration by asset ID @@ -82,7 +106,7 @@ func (c *WebProxyController) StartWebSession(ctx *gin.Context) { resp, err := web_proxy.StartWebSession(ctx, req) if err != nil { - // Return appropriate HTTP status code based on error type + // Return appropriate HTTP status code and JSON error for API if strings.Contains(err.Error(), "not found") { ctx.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) } else if strings.Contains(err.Error(), "not a web asset") { @@ -126,7 +150,7 @@ func (c *WebProxyController) ProxyWebRequest(ctx *gin.Context) { if strings.Contains(err.Error(), "invalid or expired session") || strings.Contains(err.Error(), "session expired") { c.renderSessionExpiredPage(ctx, err.Error()) } else { - ctx.JSON(http.StatusForbidden, gin.H{"error": err.Error()}) + c.renderErrorPage(ctx, "access_denied", "Access Denied", err.Error(), "Your request was blocked by the security policy.") } return } @@ -134,7 +158,7 @@ func (c *WebProxyController) ProxyWebRequest(ctx *gin.Context) { // Setup reverse proxy proxy, err := web_proxy.SetupReverseProxy(ctx, proxyCtx, c.buildTargetURLWithHost, c.processHTMLResponse, c.recordWebActivity, c.isSameDomainOrSubdomain) if err != nil { - ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + c.renderErrorPage(ctx, "server_error", "Proxy Setup Failed", err.Error(), "Failed to establish connection to the target server.") return } diff --git a/backend/internal/api/middleware/logger.go b/backend/internal/api/middleware/logger.go index 6e482db..fbb34c5 100644 --- a/backend/internal/api/middleware/logger.go +++ b/backend/internal/api/middleware/logger.go @@ -16,12 +16,24 @@ func LoggerMiddleware() gin.HandlerFunc { ctx.Next() cost := time.Since(start) - logger.L().Info(ctx.Request.URL.String(), - zap.String("method", ctx.Request.Method), - zap.Int("status", ctx.Writer.Status()), - zap.String("ip", ctx.ClientIP()), - zap.Duration("cost", cost), - ) + // Only log errors and slow requests + status := ctx.Writer.Status() + if status >= 400 || cost > 1*time.Second { + logger.L().Info(ctx.Request.URL.String(), + zap.String("method", ctx.Request.Method), + zap.Int("status", status), + zap.String("ip", ctx.ClientIP()), + zap.Duration("cost", cost), + ) + } else { + // Normal requests use debug level to reduce log noise + logger.L().Debug(ctx.Request.URL.String(), + zap.String("method", ctx.Request.Method), + zap.Int("status", status), + zap.String("ip", ctx.ClientIP()), + zap.Duration("cost", cost), + ) + } } } diff --git a/backend/internal/service/web_proxy/content.go b/backend/internal/service/web_proxy/content.go index 906df21..47e8a06 100644 --- a/backend/internal/service/web_proxy/content.go +++ b/backend/internal/service/web_proxy/content.go @@ -241,18 +241,18 @@ func ProcessHTMLResponse(resp *http.Response, assetID int, scheme, proxyHost str // Add session management JavaScript (always inject) sessionJS := fmt.Sprintf(`