From 69df359791e90c189d7e074d7715b55508c0380c Mon Sep 17 00:00:00 2001 From: jakub961241 <144362244+jakub961241@users.noreply.github.com> Date: Sun, 22 Mar 2026 00:31:32 +0100 Subject: [PATCH] fix: handle HTML responses in panel management API requests (#12260) When adding a remote panel, the API may return HTML (e.g., 401 login page) instead of JSON. The code attempted to unmarshal HTML as JSON, causing: "json umarshal resp data failed, err: invalid character '<'" Changes: - Read response body before status check to include it in errors - Add explicit 401 Unauthorized handling with clear error message - Validate Content-Type is JSON before attempting unmarshal - Include response preview in error for easier debugging Fixes #12260 --- .../req_helper/proxy_local/req_to_local.go | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/core/utils/req_helper/proxy_local/req_to_local.go b/core/utils/req_helper/proxy_local/req_to_local.go index 606428e964ab..35e58c56c390 100644 --- a/core/utils/req_helper/proxy_local/req_to_local.go +++ b/core/utils/req_helper/proxy_local/req_to_local.go @@ -62,16 +62,30 @@ func NewLocalClient(reqUrl, reqMethod string, body io.Reader, ctx *gin.Context) } defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("do request failed, err: %v", resp.Status) - } bodyByte, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("read resp body from request failed, err: %v", err) } + + if resp.StatusCode == http.StatusUnauthorized { + return nil, fmt.Errorf("authentication failed: remote panel returned 401 Unauthorized, please check API key or credentials") + } + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("do request failed, status: %s", resp.Status) + } + + contentType := resp.Header.Get("Content-Type") + if !strings.Contains(contentType, "application/json") && !strings.Contains(contentType, "text/json") { + preview := string(bodyByte) + if len(preview) > 200 { + preview = preview[:200] + } + return nil, fmt.Errorf("expected JSON response but got Content-Type: %s, body: %s", contentType, preview) + } + var respJson dto.Response if err := json.Unmarshal(bodyByte, &respJson); err != nil { - return nil, fmt.Errorf("json umarshal resp data failed, err: %v", err) + return nil, fmt.Errorf("json unmarshal resp data failed, err: %v", err) } if respJson.Code != http.StatusOK { return nil, errors.New(strings.ReplaceAll(respJson.Message, i18n.Get("ErrInternalServerKey"), ""))