From 1a3468e7c0411118100fbb221e0d0b5bbb132fa1 Mon Sep 17 00:00:00 2001 From: Marco Pedone Date: Tue, 13 Jan 2026 11:33:20 +0100 Subject: [PATCH] feat: improve error handling in GetDataXML function for better response management --- apps/backend/utils/utils.go | 45 +++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/apps/backend/utils/utils.go b/apps/backend/utils/utils.go index b863397..0cf0825 100644 --- a/apps/backend/utils/utils.go +++ b/apps/backend/utils/utils.go @@ -1,6 +1,7 @@ package utils import ( + "bytes" "compress/gzip" "encoding/xml" "fmt" @@ -85,30 +86,36 @@ func GetDataXML[T any](url string) (T, error) { } defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - body, _ := io.ReadAll(resp.Body) - _, _ = saveFailedRequest("non_200", url, req.Header, resp.Header, resp.StatusCode, body, "status error") - return result, fmt.Errorf("Failed to fetch url %s: status error: %d", url, resp.StatusCode) - } - // handle gzip decompression if server used it - var raw []byte - if strings.Contains(resp.Header.Get("Content-Encoding"), "gzip") { - gz, gerr := gzip.NewReader(resp.Body) - if gerr != nil { - body, _ := io.ReadAll(resp.Body) // best-effort - _, _ = saveFailedRequest("gzip_error", url, req.Header, resp.Header, resp.StatusCode, body, gerr.Error()) - return result, fmt.Errorf("gzip new reader: %w", gerr) - } - defer gz.Close() - raw, err = io.ReadAll(gz) - } else { - raw, err = io.ReadAll(resp.Body) - } + raw, err := io.ReadAll(resp.Body) if err != nil { _, _ = saveFailedRequest("read_error", url, req.Header, resp.Header, resp.StatusCode, raw, err.Error()) return result, fmt.Errorf("failed to read response: %w", err) } + if resp.StatusCode != http.StatusOK { + _, _ = saveFailedRequest("non_200", url, req.Header, resp.Header, resp.StatusCode, raw, "status error") + return result, fmt.Errorf("Failed to fetch url %s: status error: %d", url, resp.StatusCode) + } + + // handle gzip decompression if server used it + isGzipHeader := strings.Contains(strings.ToLower(resp.Header.Get("Content-Encoding")), "gzip") + isGzipMagic := len(raw) > 2 && raw[0] == 0x1f && raw[1] == 0x8b + + if isGzipHeader || isGzipMagic { + gz, gerr := gzip.NewReader(bytes.NewReader(raw)) + if gerr != nil { + _, _ = saveFailedRequest("gzip_error", url, req.Header, resp.Header, resp.StatusCode, raw, gerr.Error()) + return result, fmt.Errorf("gzip new reader: %w", gerr) + } + defer gz.Close() + decompressed, err := io.ReadAll(gz) + if err != nil { + _, _ = saveFailedRequest("gzip_read_error", url, req.Header, resp.Header, resp.StatusCode, raw, err.Error()) + return result, fmt.Errorf("gzip read: %w", err) + } + raw = decompressed + } + // attempt to unmarshal if err := xml.Unmarshal(raw, &result); err != nil { _, _ = saveFailedRequest("unmarshal_error", url, req.Header, resp.Header, resp.StatusCode, raw, err.Error())