From 2e15d5ef2d911d48e9ea52b5726f7ee9f57ed608 Mon Sep 17 00:00:00 2001 From: anveshthakur Date: Sat, 28 Sep 2024 20:05:35 +0530 Subject: [PATCH 1/3] enhanced error handling for openweathermap api errors --- backends/openweathermap.org.go | 70 ++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/backends/openweathermap.org.go b/backends/openweathermap.org.go index 1eae102..cb85c03 100644 --- a/backends/openweathermap.org.go +++ b/backends/openweathermap.org.go @@ -4,13 +4,15 @@ import ( "encoding/json" "flag" "fmt" - "github.com/schachmat/wego/iface" "io" "log" "net/http" "regexp" + "strconv" "strings" "time" + + "github.com/schachmat/wego/iface" ) type openWeatherConfig struct { @@ -22,12 +24,12 @@ type openWeatherConfig struct { type openWeatherResponse struct { Cod string `json:"cod"` City struct { - Name string `json:"name"` - Country string `json:"country"` - TimeZone int64 `json: "timezone"` + Name string `json:"name"` + Country string `json:"country"` + TimeZone int64 `json: "timezone"` // sunrise/sunset are once per call SunRise int64 `json: "sunrise"` - SunSet int64 `json: "sunset"` + SunSet int64 `json: "sunset"` } `json:"city"` List []dataBlock `json:"list"` } @@ -55,6 +57,15 @@ type dataBlock struct { } `json:"rain"` } +type openWeatherErrorReponse struct { + Cod any `json:"cod"` + Message string `json:"message"` +} + +func (e openWeatherErrorReponse) Error() string { + return fmt.Sprintf("Error Response from openweathermap.org (%v): %s", e.Cod, e.Message) +} + const ( openweatherURI = "http://api.openweathermap.org/data/2.5/forecast?%s&appid=%s&units=metric&lang=%s" ) @@ -82,15 +93,52 @@ func (c *openWeatherConfig) fetch(url string) (*openWeatherResponse, error) { if c.debug { fmt.Printf("Response (%s):\n%s\n", url, string(body)) } + if res.StatusCode != 200 { + err = openWeatherErrorReponseHandler(body, url) + return nil, err + } else { + var resp openWeatherResponse + if err = json.Unmarshal(body, &resp); err != nil { + return nil, fmt.Errorf("Unable to unmarshal response (%s): %v\nThe json body is: %s", url, err, string(body)) + } + if resp.Cod != "200" { + return nil, fmt.Errorf("Erroneous response body: %s", string(body)) + } + return &resp, nil + } +} + +func openWeatherErrorReponseHandler(body []byte, url string) error { + var resp openWeatherErrorReponse + + if err := resp.UnmarshalJSON(body); err != nil { + return fmt.Errorf("Unable to unmarshal error response (%s): %v\nThe json body is: %s", url, err, string(body)) + } + + return resp +} - var resp openWeatherResponse - if err = json.Unmarshal(body, &resp); err != nil { - return nil, fmt.Errorf("Unable to unmarshal response (%s): %v\nThe json body is: %s", url, err, string(body)) +func (r *openWeatherErrorReponse) UnmarshalJSON(data []byte) error { + var raw struct { + Cod interface{} `json:"cod"` + Message string `json:"message"` } - if resp.Cod != "200" { - return nil, fmt.Errorf("Erroneous response body: %s", string(body)) + + if err := json.Unmarshal(data, &raw); err != nil { + return err } - return &resp, nil + + switch v := raw.Cod.(type) { + case string: + r.Cod = v + case float64: + r.Cod = strconv.Itoa(int(v)) + default: + return fmt.Errorf("unexpected cod type") + } + + r.Message = raw.Message + return nil } func (c *openWeatherConfig) parseDaily(dataInfo []dataBlock, numdays int) []iface.Day { From eb56ff3c97c63745d4c5d15f36fc325196952a25 Mon Sep 17 00:00:00 2001 From: anveshthakur Date: Mon, 7 Oct 2024 00:09:02 +0530 Subject: [PATCH 2/3] changed Cod to Code and removed the extra else from fetch fn --- backends/openweathermap.org.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/backends/openweathermap.org.go b/backends/openweathermap.org.go index cb85c03..7160007 100644 --- a/backends/openweathermap.org.go +++ b/backends/openweathermap.org.go @@ -58,12 +58,12 @@ type dataBlock struct { } type openWeatherErrorReponse struct { - Cod any `json:"cod"` + Code any `json:"cod"` Message string `json:"message"` } func (e openWeatherErrorReponse) Error() string { - return fmt.Sprintf("Error Response from openweathermap.org (%v): %s", e.Cod, e.Message) + return fmt.Sprintf("Error Response from openweathermap.org (%v): %s", e.Code, e.Message) } const ( @@ -93,19 +93,20 @@ func (c *openWeatherConfig) fetch(url string) (*openWeatherResponse, error) { if c.debug { fmt.Printf("Response (%s):\n%s\n", url, string(body)) } + if res.StatusCode != 200 { err = openWeatherErrorReponseHandler(body, url) return nil, err - } else { - var resp openWeatherResponse - if err = json.Unmarshal(body, &resp); err != nil { - return nil, fmt.Errorf("Unable to unmarshal response (%s): %v\nThe json body is: %s", url, err, string(body)) - } - if resp.Cod != "200" { - return nil, fmt.Errorf("Erroneous response body: %s", string(body)) - } - return &resp, nil } + + var resp openWeatherResponse + if err = json.Unmarshal(body, &resp); err != nil { + return nil, fmt.Errorf("Unable to unmarshal response (%s): %v\nThe json body is: %s", url, err, string(body)) + } + if resp.Cod != "200" { + return nil, fmt.Errorf("Erroneous response body: %s", string(body)) + } + return &resp, nil } func openWeatherErrorReponseHandler(body []byte, url string) error { @@ -130,9 +131,9 @@ func (r *openWeatherErrorReponse) UnmarshalJSON(data []byte) error { switch v := raw.Cod.(type) { case string: - r.Cod = v + r.Code = v case float64: - r.Cod = strconv.Itoa(int(v)) + r.Code = strconv.Itoa(int(v)) default: return fmt.Errorf("unexpected cod type") } From fdb55e2610a5d549cba16e98aab04e7a08f014d2 Mon Sep 17 00:00:00 2001 From: anveshthakur Date: Mon, 7 Oct 2024 00:44:41 +0530 Subject: [PATCH 3/3] changed the Cod to Code from Unmarshal fn --- backends/openweathermap.org.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/openweathermap.org.go b/backends/openweathermap.org.go index 7160007..c8192d9 100644 --- a/backends/openweathermap.org.go +++ b/backends/openweathermap.org.go @@ -121,7 +121,7 @@ func openWeatherErrorReponseHandler(body []byte, url string) error { func (r *openWeatherErrorReponse) UnmarshalJSON(data []byte) error { var raw struct { - Cod interface{} `json:"cod"` + Code interface{} `json:"cod"` Message string `json:"message"` } @@ -129,7 +129,7 @@ func (r *openWeatherErrorReponse) UnmarshalJSON(data []byte) error { return err } - switch v := raw.Cod.(type) { + switch v := raw.Code.(type) { case string: r.Code = v case float64: