feat: improve error handling in GetDataXML function for better response management

This commit is contained in:
Marco Pedone 2026-01-13 11:33:20 +01:00
parent 08212355eb
commit 1a3468e7c0

View file

@ -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())