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

[bugfix] handle unexpected response bodies #492

Merged
merged 10 commits into from
Nov 4, 2019
Merged

[bugfix] handle unexpected response bodies #492

merged 10 commits into from
Nov 4, 2019

Conversation

adsteel
Copy link
Contributor

@adsteel adsteel commented Oct 16, 2019

Addresses #491

lib/intercom/request.rb Outdated Show resolved Hide resolved
@adsteel adsteel changed the title [bugfix] always throw a specific error if parsed_body is nil [bugfix] handle unexpected response bodies Nov 1, 2019
@adsteel
Copy link
Contributor Author

adsteel commented Nov 1, 2019

@jonnyom okay, take 2. My commits are in order, and probably best reviewed that way. Tests pass at every commit, but please feel free to double check that. I think I came up with a better solution that also did not involve a breaking change. Let me know what you think.


parsed_body = extract_response_body(response)

return nil if parsed_body.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.

This line and https://github.com/intercom/intercom-ruby/pull/492/files#diff-e0313851110ec5f90dfd3a2befbc94f3R123 are to prevent any existing tests from breaking, in case users are depending on this behavior.

@@ -7,27 +7,27 @@
it 'raises an error when a html error page rendered' do
response = OpenStruct.new(:code => 500)
req = Intercom::Request.new('path/', 'GET')
proc {req.parse_body('<html>something</html>', response)}.must_raise(Intercom::ServerError)
_(proc {req.parse_body('<html>something</html>', response)}).must_raise(Intercom::ServerError)
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for this. Do you have happen to have a link to Minitest's documentation that outlines this behaviour?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, I see you've refactored this later on. Nice! 👍

@@ -129,19 +129,21 @@ def decode(content_encoding, body)
end

def raise_errors_on_failure(res)
if res.code.to_i.eql?(404)
code = res.code.to_i
Copy link
Contributor

Choose a reason for hiding this comment

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

💯

def self.post(path, form_data)
new(path, method_with_body(Net::HTTP::Post, path, form_data))
end
private
Copy link
Contributor

Choose a reason for hiding this comment

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

To make it a little clearer, can we inline the private methods please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course! Done.

@jonnyom
Copy link
Contributor

jonnyom commented Nov 4, 2019

This looks great, thank you @adsteel

One small stylistic change that I think could improve readability in the Request class (specifically inlining private methods), but other than that this looks like a very elegant solution.

@adsteel
Copy link
Contributor Author

adsteel commented Nov 4, 2019

@jonnyom I added a commit converting to the inlined private definition. Let me know if there's anything else!

@jonnyom
Copy link
Contributor

jonnyom commented Nov 4, 2019

@adsteel this looks great, thanks a lot!

If you'd like to just rebase off the master branch (Looks like a readme change) then I think we can merge thiks.

If the JSON parsing errors, `parsed_body` is `nil` and the following
line raises the error.
This will help us better reason about which methods should have tests,
and which methods other objects are depending on specific behavior from.
Done as a step toward fixing a bug in `#parse_body`

- Moves client test to client_spec.rb
- Replaces parse_body tests with higher level tests
- Makes parse_body private
- Organizes and cleans up the request_spec file generally
`parse_body` was doing three things:
  - checking for response errors
  - handling parse errors
  - actually parsing the response body

We get some cleaner code by separating the parsing from the response
state checking.
Some responses do not have an expected error code and have non-JSON
bodies that fail to parse. The unexpected `nil` caused runtime errors.
This fix raises an error on those responses with more information that
will allow developers to find a path forward, either by more fixes to
this gem or by handling the new error in their own code.

I'm giving this version bump a patch level bump because it looks like
all existing functionality is preserved. We will now simply get better
information instead of `undefined method '[]' for nil:NilClass`.

Addresses #491
@adsteel
Copy link
Contributor Author

adsteel commented Nov 4, 2019

@jonnyom rebased with master.

Copy link
Contributor

@jonnyom jonnyom left a comment

Choose a reason for hiding this comment

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

Great stuff, thanks a lot @adsteel

I'll try to get a release out for this in the next day or two.

@jonnyom jonnyom merged commit dc7d65b into intercom:master Nov 4, 2019
This was referenced Nov 11, 2019
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.

None yet

2 participants