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

Standardize error return from HTTP requests #363

Merged
merged 4 commits into from
Nov 30, 2024
Merged

Conversation

benjaminjkraft
Copy link
Collaborator

This makes the HTTP request errors As-able, so you can retry on rate limit errors, or whatever.

Fixes #333, replaces #352 (I just added docs).

I have:

  • Written a clear PR title and description (above)
  • Signed the Khan Academy CLA
  • Added tests covering my changes, if applicable
  • Included a link to the issue fixed, if applicable
  • Included documentation, for new features
  • Added an entry to the changelog

@benjaminjkraft benjaminjkraft merged commit adb9dd6 into main Nov 30, 2024
8 checks passed
@benjaminjkraft benjaminjkraft deleted the benkraft.http-error branch November 30, 2024 19:55
Copy link
Member

@csilvers csilvers left a comment

Choose a reason for hiding this comment

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

I'm late to the party, but this looks good to me! I appreciate being able to introspect on errors.


// Error implements the error interface for HTTPError.
func (e *HTTPError) Error() string {
return fmt.Sprintf("returned error %v: %s", e.StatusCode, e.Body)
Copy link
Member

Choose a reason for hiding this comment

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

This error-text can be hard to parse when the body is the empty string (or just whitespace), so you may want to do %#v instead of %s, or something like >>>%s<<<. Though maybe it's not going to matter much in practice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it needs to be %s to convert the bytes to string, but I can at least add quotes!

benjaminjkraft added a commit that referenced this pull request Nov 30, 2024
Thanks to Craig for the suggestion! Since people may have, before #363,
been parsing the text, I mentioned it as a breaking change, although I
imagine most people are parsing just the code.
@benjaminjkraft benjaminjkraft mentioned this pull request Nov 30, 2024
6 tasks
benjaminjkraft added a commit that referenced this pull request Dec 1, 2024
Thanks to Craig for the suggestion! Since people may have, before #363,
been parsing the text, I mentioned it as a breaking change, although I
imagine most people are parsing just the code, not the text.

I have:
- [x] Written a clear PR title and description (above)
- [x] Signed the [Khan Academy CLA](https://www.khanacademy.org/r/cla)
- [x] Added tests covering my changes, if applicable
- [x] Included a link to the issue fixed, if applicable
- [x] Included documentation, for new features
- [x] Added an entry to the changelog
@HaraldNordgren
Copy link
Contributor

HaraldNordgren commented Dec 2, 2024

Hi @benjaminjkraft and @csilvers !

This is really nice, and I wonder if we can go further still?

This is how my logic was changed to fit with these latest changes:

-                       expected: errors.New("returned error 422 Unprocessable Entity: {\"errors\":[{\"message\":\" is not a valid MealType\",\"path\":[\"variable\",\"request\",\"mealType\"],\"extensions\":{\"code\":\"GRAPHQL_VALIDATION_FAILED\"}}],\"data\":null}"),
+                       expected: &graphql.HTTPError{
+                               Body:       "{\"errors\":[{\"message\":\" is not a valid MealType\",\"path\":[\"variable\",\"request\",\"mealType\"],\"extensions\":{\"code\":\"GRAPHQL_VALIDATION_FAILED\"}}],\"data\":null}",
+                               StatusCode: 422,
+                       },

If we go one step further, should be able to expose the underlying Response type, instead of flattening into a string:

type BaseResponse[T any] struct {
	Data       T                      `json:"data"`
	Extensions map[string]interface{} `json:"extensions,omitempty"`
	Errors     gqlerror.List          `json:"errors,omitempty"`
}

type Response BaseResponse[any]

Notice that the structure of the data is my diff already matches exactly with type Response.

PR for a proposed implementation: #366

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Standardise the error return from http request
4 participants