-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Unexpected 401 Unauthorized response status when action is public #4788
Conversation
test 'public action should return notification payload with 500 status' do | ||
begin | ||
subscriber = ActiveSupport::Notifications.subscribe /process_action.action_controller/ do |_name, _start, _finish, _id, payload| | ||
assert_equal 500, payload[:status] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is basically a test case copied from the above one, but using a public action that raises an error (see rest of commit)
This assertion fails unexpectedly:
devise(master)% ruby -I"lib:test" test/integration/authenticatable_test.rb -n /public/
==> Devise.orm = :active_record
Expected string default value for '--orm'; got false (boolean)
Run options: -n /public/ --seed 25980
# Running:
F
Failure:
AuthenticationOthersTest#test_public_action_should_return_notification_payload_with_500_status [test/integration/authenticatable_test.rb:564]:
Expected: 500
Actual: 401
I dug into this a little bit, because we're running into the same wrong log messages. In our case the investigation was triggered by Since this change to Rails, That's good! BUT the That means the code added/changed in #4375 is incorrect. Making it correct would either mean setting So, is there another way to check if an exception was thrown? I don't know of any, especially not in the context in which If there's no other way, maybe the whole idea of assuming status 401 does not hold anymore? It's based on a pretty old commit for a different mechanism: Maybe we should just get rid of it and move the setting of |
@rafaelsales The proposed fix still contains a reference to |
@mrnugget That value is present when the instrument subscription is called, it's just not present when Here's where it gets set by Rails: I agree with the "scoping this to devise/warden-enabled controllers" though. I could add this check in the instrument: |
@rafaelsales Ahh, thanks for clearing that up!
I know that this might sound excessive, but I'm kind of wary of calling a method (trough an indirect |
Thank you @rafaelsales for taking the time to resolve this. I’m witnessing this too after upgrading to 5.1.4, when a 500 exception is returned within action. |
I'm more included to revert the previous PR. The right place to implement that is inside the controller instance, not inside a new subscriber. |
If that option is on the table, I think it's the best one. |
@rafaelfranca @mrnugget Yeah, I also agree that reverting to the old approach is cleaner. I just tried reverting to the old implementation while keeping the specs to make sure a regression is not introduced in the future, but I couldn't get this spec that @fbbergamo wrote originally to work. I keep getting:
|
I'm going to revert the previous PR and release a patch version - we also have other bug fixes to include in this release - then we can think of another solution to the previous issue. |
Thanks! |
Did this only get reverted back and never actually solved? |
@AndrewSouthpaw I only saw your comment now while I was digging for this. Indeed, it wasn't solved yet. We decided to revert because we needed to release a version with some important fixes, but this wasn't addressed yet. |
Done! |
The PR #4375 broke the logging in my app when I upgraded from 4.3.0 to 4.4.0, and 4.4.1 is still broken. I'm on Rails 5.1.4
I noticed that the logs in my app had
Completed 401 Unauthorized
when the actual response received by the client was a 500 Internal Server Error.I reported this in #4375 (comment) but @tegon suggested to submit this PR with a failing test case that reproduces the bug.
Investigation
I dug in a little bit and I found out that in the following method, the
payload[:exception]
always returnsnil
even if a public action raises an error, so the401
status is added to the payload. Also, Rails didn't add the 500 status at this point yet, sopayload[:status]
isnil
as wellhttps://github.com/plataformatec/devise/blob/f39c6fd92774cb66f96f546d8d5e8281542b4e78/lib/devise/controllers/helpers.rb#L16-L19
Solution
I couldn't figure out the proper solution other than reverting that PR yet. I'll spend some time investigating later today, but it would be great to have some input from @fbbergamoUse
ActiveSupport::Notifications.instrument
instead of overridingappend_info_to_payload
since the former is called later in the stack, for which thepayload[:exception]
is present when an exception was raised