Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhanced error handling for open weather API errors #192

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
changed Cod to Code and removed the extra else from fetch fn
  • Loading branch information
anveshthakur committed Oct 6, 2024
commit eb56ff3c97c63745d4c5d15f36fc325196952a25
27 changes: 14 additions & 13 deletions backends/openweathermap.org.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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 {
Expand All @@ -130,9 +131,9 @@ func (r *openWeatherErrorReponse) UnmarshalJSON(data []byte) error {

switch v := raw.Cod.(type) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is weird: can the type really be a string? Codes are usually only integers, so using a float64 here makes no sense to me. According to the docs this should always be an integer: https://openweathermap.org/api/one-call-3#errorstructure

Copy link
Author

@anveshthakur anveshthakur Oct 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String and Integer Cod Value -

so, if you see this

They are sending a string in few cases like this 404 and 200 but for 400 it is an integer

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Float64?

The reason why I am comparing type with float64 is because I am taking Code as a type of interface and when go unmarshals an interface value for numbers it returns the number with the type of float64

Source:
https://stackoverflow.com/questions/39152481/unmarshaling-a-json-integer-to-an-empty-interface-results-in-wrong-type-assertio

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")
}
Expand Down