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

Raise exception on nil status #1042

Merged
merged 2 commits into from
Oct 15, 2019

Conversation

jonnyom
Copy link
Contributor

@jonnyom jonnyom commented Sep 30, 2019

Description

If a host responds badly to HTTP requests it's possible for the HTTP status to be returned nil.
It makes sense to raise an exception here that can be rescued from and handled appropriately instead of silently allowing them through.
Fixes #1028

Todos

List any remaining work that needs to be done, i.e:

  • Tests
  • Documentation

@olleolleolle
Copy link
Member

This got me curious about the case where the response code is numeric but in an invalid range.

(I'm out traveling, so this happens from a phone.)

@jonnyom
Copy link
Contributor Author

jonnyom commented Sep 30, 2019

That's a good point. A base case here for any invalid status could be useful

@@ -13,7 +13,10 @@ def initialize(exc, response = nil)
super(exc.message)
@wrapped_exception = exc
elsif exc.respond_to?(:each_key)
super("the server responded with status #{exc[:status]}")
nil_status_message = 'the server responded with a nil status'
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it make sense to say the server responded with a nil status if the server did not send a status Header at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a fair point, maybe a more explicit message, something like status couldn't be derived from server response?

Copy link
Contributor

Choose a reason for hiding this comment

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

I like it, I'd say move it down into the error itself as well rather than in this base error class

@@ -69,6 +72,10 @@ class ConflictError < ClientError
class UnprocessableEntityError < ClientError
end

# Raised by Faraday::Response::RaiseError in case of a nil status in response.
class NilStatusError < ClientError
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
class NilStatusError < ClientError
class NilStatusError < ServerError

Copy link
Contributor

Choose a reason for hiding this comment

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

  class NilStatusError < ServerError
    def initialize(exc = nil, response = nil)
      message = 'http status could not be derived from the server response'
      super(message, response)
    end
  end

@@ -28,6 +28,8 @@ def on_complete(env)
raise Faraday::ConflictError, response_values(env)
when 422
raise Faraday::UnprocessableEntityError, response_values(env)
when nil
raise Faraday::NilStatusError, response_values(env)
Copy link
Contributor

Choose a reason for hiding this comment

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

If you make the suggestions I made above, you'll need to change this line as well
raise Faraday::NilStatusError, nil, response_values(env)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good 👍 I'll get to this later today

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So passing nil to this actually caused a bunch of issues for me when setting the backtrace. So I've opted to not pass it at all. Let me know if there's a better way around this.

Copy link
Contributor

Choose a reason for hiding this comment

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

🤦‍♂ silly me, we're not using Faraday::NilStatusError.new so the backtrace is implicit

@jonnyom
Copy link
Contributor Author

jonnyom commented Oct 1, 2019

This is failing lint on an unrelated file
In Circle

Inspecting 100 files
.........W..........................................................................................

Offenses:

lib/faraday/adapter/em_http_ssl_patch.rb:62:34: W: Lint/SendWithMixinArgument: Use include EmHttpSslPatch instead of send(:include, EmHttpSslPatch).
EventMachine::HttpStubConnection.send(:include, EmHttpSslPatch)
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Locally

~/D/p/faraday ❯❯❯ rubocop                                                                                                                             raise-exception-on-nil-status
Inspecting 100 files
....................................................................................................

100 files inspected, no offenses detected
~/D/p/faraday ❯❯❯ rubocop --require rubocop/formatter/junit_formatter \                                                                               raise-exception-on-nil-status
        --require rubocop-performance \
        --format progress \
        --format RuboCop::Formatter::JUnitFormatter \
        --out ~/test-results/linting/rubocop.xml
Inspecting 100 files
.........W..........................................................................................

Offenses:

lib/faraday/adapter/em_http_ssl_patch.rb:62:34: W: Lint/SendWithMixinArgument: Use include EmHttpSslPatch instead of send(:include, EmHttpSslPatch).
EventMachine::HttpStubConnection.send(:include, EmHttpSslPatch)
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

100 files inspected, 1 offense detected

I don't have permissions to retrigger the build, but this passes locally without JUnit, but once I've installed it it fails

@olleolleolle
Copy link
Member

olleolleolle commented Oct 1, 2019

I'd appreciate a separate PR for the linting fix. <3

@BobbyMcWho
Copy link
Contributor

I had implemented it in #1043, I can open a new PR to target it alone

@jonnyom
Copy link
Contributor Author

jonnyom commented Oct 1, 2019

Cool! I'm happy to roll it into this either @BobbyMcWho but its own PR would be cleaner I guess

@BobbyMcWho
Copy link
Contributor

@olleolleolle merged it, @jonnyom you should be able to git pull [your lostisland remote] 0.16.x --rebase and be good to (force) push back up to your branch to get that change

@jonnyom jonnyom force-pushed the raise-exception-on-nil-status branch from 0569535 to 538e2ae Compare October 2, 2019 09:41
@jonnyom jonnyom changed the base branch from master to 0.16.x October 2, 2019 09:48
@jonnyom jonnyom force-pushed the raise-exception-on-nil-status branch from 538e2ae to 6adf096 Compare October 2, 2019 09:48
@@ -83,6 +83,14 @@ def initialize(exc = 'timeout', response = nil)
end
end

# Raised by Faraday::Response::RaiseError in case of a nil status in response.
class NilStatusError < ServerError
def initialize(response = nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

I submitted a PR to your fork, this will need two params to handle the stack trace that's sent

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I saw that, just lifted what you had and popped it in here, easier than merging things into the fork

@jonnyom
Copy link
Contributor Author

jonnyom commented Oct 9, 2019

@olleolleolle @BobbyMcWho just wanted to give this a bump

Copy link
Member

@technoweenie technoweenie left a comment

Choose a reason for hiding this comment

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

Thanks for adding this! I identified a really minor change, but I think this is ready to go. However, the original PR has an unchecked Documentation item. Did you plan on updating docs/middleware/response/raise_error.md in this PR too? I'm happy to take this on in a new PR, as I'd like to reformat the list of status codes inside the

 block.

Comment on lines +31 to +32
when nil
raise Faraday::NilStatusError, response: response_values(env)
Copy link
Member

Choose a reason for hiding this comment

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

  1. I'd rather have the nil check at the bottom, since it's the least likely to occur than any numerical status. Pretty minor issue, so I'm not sure if it's worth the effort :)
  2. I like passing response as a named variable, rather than positional. I've added a note to the v2 wishlist (Faraday Wishlist #953) to make this consistent with the other error types.

@jonnyom
Copy link
Contributor Author

jonnyom commented Oct 15, 2019

@technoweenie if you want to refactor it then maybe we should just merge this and you can make that refactor including these changes?

(I also wasn't sure where the documentation was, which is why I didn't add it)

Thanks!

@technoweenie technoweenie merged commit 0f1eea4 into lostisland:0.16.x Oct 15, 2019
@technoweenie
Copy link
Member

Thanks @jonnyom! I'll take care of the docs.

This was referenced Oct 15, 2019
technoweenie added a commit that referenced this pull request Oct 17, 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.

5 participants