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

Enhance reliability of how we make requests and parse errors #108

Merged
merged 1 commit into from
Aug 30, 2022

Conversation

sergiught
Copy link
Contributor

@sergiught sergiught commented Aug 27, 2022

Description

The push for these improvements originally starts from this issue: auth0/terraform-provider-auth0#36, where under certain rare occasions we could get non HTML body in the responses and then throw an obscure error message, not really understanding what's happening. We try to make things a bit more obvious in this PR and increase the reliability of how we make http requests, there were also a couple of occasions when we didn't correctly close the response body. Further comments are provided in the code.

References

Testing

  • This change adds test coverage for new/changed/fixed functionality

Checklist

  • I have read and agreed to the terms within the Auth0 Code of Conduct.
  • I have read the Auth0 General Contribution Guidelines.
  • I have reviewed my own code beforehand.
  • I have added documentation for new/changed functionality in this PR.
  • All active GitHub checks for tests, formatting, and security are passing.
  • The correct base branch is being used, if not main.

@codecov-commenter
Copy link

codecov-commenter commented Aug 27, 2022

Codecov Report

Merging #108 (6aec75e) into main (7fd1c74) will increase coverage by 0.40%.
The diff coverage is 68.42%.

@@            Coverage Diff             @@
##             main     #108      +/-   ##
==========================================
+ Coverage   94.75%   95.16%   +0.40%     
==========================================
  Files          37       37              
  Lines        5799     5792       -7     
==========================================
+ Hits         5495     5512      +17     
+ Misses        244      226      -18     
+ Partials       60       54       -6     
Impacted Files Coverage Δ
management/user.go 83.06% <41.66%> (-0.74%) ⬇️
management/management_request.go 85.35% <56.25%> (+1.24%) ⬆️
management/anomaly.go 56.52% <66.66%> (+6.52%) ⬆️
management/guardian.go 93.07% <66.66%> (ø)
management/branding.go 77.77% <100.00%> (+8.85%) ⬆️
management/job.go 79.06% <100.00%> (+15.13%) ⬆️
management/management_error.go 100.00% <100.00%> (+30.00%) ⬆️
... and 2 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@sergiught sergiught self-assigned this Aug 27, 2022
Copy link
Contributor Author

@sergiught sergiught left a comment

Choose a reason for hiding this comment

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

Adding a few comments to aid with reviewing.

return false, nil
}

return false, newError(res.Body)
return false, newError(response)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We've changed the signature of the newError func to accept the entire response so we can have access to the status code as well. Further clarifications as to why this is needed are provided in the comments below.

Comment on lines -171 to -185
req, err := m.NewRequest("PUT", m.URI("branding", "templates", "universal-login"), ul.Body, opts...)
if err != nil {
return err
}

res, err := m.Do(req)
if err != nil {
return err
}

if res.StatusCode >= http.StatusBadRequest {
return newError(res.Body)
}

return nil
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All of this part was just replicating what the m.Request() was doing with the difference that we were not correctly closing the response body in this func, causing memory leaks.

Comment on lines +149 to +165
request, err := m.NewRequest("POST", m.URI("guardian", "enrollments", "ticket"), t, opts...)
if err != nil {
return EnrollmentTicket{}, err
}

res, err := m.Do(req)
response, err := m.Do(request)
if err != nil {
return EnrollmentTicket{}, err
}
defer res.Body.Close()
defer response.Body.Close()

if res.StatusCode != http.StatusOK {
return EnrollmentTicket{}, newError(res.Body)
if response.StatusCode != http.StatusOK {
return EnrollmentTicket{}, newError(response)
}

var out EnrollmentTicket
err = json.NewDecoder(res.Body).Decode(&out)
err = json.NewDecoder(response.Body).Decode(&out)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately we couldn't do the same thing as we did in the branding.go file and simply replace all the logic with a call to m.Request. This is because m.Request expects to change in place the same object that gets passed through with the response data. In this case we pass CreateEnrollmentTicket but return an EnrollmentTicket which are 2 different structs.

Comment on lines -129 to -153
req, err := http.NewRequest("POST", m.URI("jobs", "users-imports"), &payload)
if err != nil {
return err
}
req.Header.Add("Content-Type", mp.FormDataContentType())

for _, option := range opts {
option.apply(req)
}

res, err := m.Do(req)
if err != nil {
return err
}

if res.StatusCode < http.StatusOK || res.StatusCode >= http.StatusBadRequest {
return newError(res.Body)
}

if res.StatusCode != http.StatusNoContent {
defer res.Body.Close()
return json.NewDecoder(res.Body).Decode(j)
}
opts = append(opts, Header("Content-Type", mp.FormDataContentType()))

return nil
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again, this is doing exactly what the m.Request is doing so we replace it after appending the opts correctly.

m := &managementError{}
if err := json.NewDecoder(r).Decode(m); err != nil {
return err
func newError(response *http.Response) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Quite a few improvements to this func:

  • Preserve status code from the response instead of relying purely that the body contains the status code as well
  • Preserve status code when we fail to decode the response when this is not a valid JSON

}

if response.StatusCode != http.StatusNoContent && response.StatusCode != http.StatusAccepted {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This check was replaced by if len(responseBody) > 0 && string(responseBody) != "{}"

@sergiught sergiught force-pushed the patch/refactor-requests-mechanism branch from 25cf36d to 6aec75e Compare August 27, 2022 14:37
@sergiught sergiught marked this pull request as ready for review August 27, 2022 14:39
@sergiught sergiught requested a review from a team as a code owner August 27, 2022 14:39
@sergiught sergiught requested review from Widcket and willvedd August 30, 2022 16:55
Copy link
Contributor

@Widcket Widcket left a comment

Choose a reason for hiding this comment

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

Nice improvements! 👏🏼

@sergiught sergiught merged commit d65b4bb into main Aug 30, 2022
@sergiught sergiught deleted the patch/refactor-requests-mechanism branch August 30, 2022 18:45
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.

3 participants