feat: improve error handling in GetDataXML function for better response management
This commit is contained in:
parent
08212355eb
commit
1a3468e7c0
1 changed files with 26 additions and 19 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -85,30 +86,36 @@ func GetDataXML[T any](url string) (T, error) {
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
raw, err := io.ReadAll(resp.Body)
|
||||||
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)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _ = saveFailedRequest("read_error", url, req.Header, resp.Header, resp.StatusCode, raw, err.Error())
|
_, _ = saveFailedRequest("read_error", url, req.Header, resp.Header, resp.StatusCode, raw, err.Error())
|
||||||
return result, fmt.Errorf("failed to read response: %w", err)
|
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
|
// attempt to unmarshal
|
||||||
if err := xml.Unmarshal(raw, &result); err != nil {
|
if err := xml.Unmarshal(raw, &result); err != nil {
|
||||||
_, _ = saveFailedRequest("unmarshal_error", url, req.Header, resp.Header, resp.StatusCode, raw, err.Error())
|
_, _ = saveFailedRequest("unmarshal_error", url, req.Header, resp.Header, resp.StatusCode, raw, err.Error())
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue