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
Catchall error block fails to catch direct decendants of Exception #1548
Comments
@thesecretmaster Thanks for filing an issue. What's your motivation to use If you have a good justification regarding your motivation and have a good patch (this meant the patch must not break other tested behavior), please submit a PR. Let's discuss based on the patch. P.S.
|
With |
I'm closing unless more information can be provided as I am seeing the same thing mentioned by @dentarg. |
I'd suggest re-opening this issue. The problem here is that the behavior contracts the documentation. In the README, it shows the following example, acting as a catch-all for any error. error do
'Sorry there was a nasty error - ' + env['sinatra.error'].message
end However, this does not work as described. Consider the following app: require 'sinatra'
set :raise_errors, true
set :show_exceptions, false
class FooError < RuntimeError; end
get '/' do
raise FooError, 'wat'
end
error do
"Sorry there was a nasty error"
end We expect the "Sorry there was a nasty error" message to appear, but it does not. In order for the message to appear we change the
I will attempt to write a failing test that demonstrates this behavior. |
I should be more specific: The behavior depends on If |
I added #1914 as an example |
Isn't #1914 showing the opposite? sinatra/test/mapped_error_test.rb Lines 121 to 130 in 70151c9
|
Just noting a thing here as I looked it up:
Looks like that comes from 2e0030f |
Is the bug that any error handlers are called when |
Sorry, let me explain what I meant. I was trying to say that when
That's difficult to say. Here's why: Consider the test added in 4e71959, which now appears on line 110 of mapped_error_test.rb That test, which has been in the codebase for 13 years, seems to suggest that error handlers should be invoked when Based on that information, I added an additional test, which demonstrates that the error handler is not invoked if the handler is declared for So, I would expect the test that I added in #1914 to also pass. If you compare the original test that I mentioned above from 4e71959, with the test that I added, you can see the only material difference is the class that the error handler is invoked for -- the original test uses Here they are together (as they appear in the test file): it "calls error handlers before raising errors even when raise_errors is set" do
mock_app do
set :raise_errors, true
error(FooError) { "she's there." }
get('/') { raise FooError }
end
get '/'
assert_equal 500, status
assert_equal "she's there.", body
end
it "uses the Exception handler before raising errors even when raise_errors is set" do
mock_app do
set :raise_errors, true
error(Exception) { "Parent handler" }
get('/') { raise FooError }
end
get '/'
assert_equal 500, status
assert_equal "Parent handler", body
end It seems to me that both of these tests should pass. Right now only the first test passes, while the second test fails. What do you think? If you agree, I am happy to work on #1914 to achieve that result. |
Thanks for clarifying and providing more background info. I guess it depends on how you view your use of the catch-all ( I'm starting to think the existing behaviour is the intentional behaviour and not a bug (you want your tests to raise errors even if you have a catch all defined). |
Ok. If I am writing controller tests for an application that had a default catch-all error handler, and I want to write a test for the default catch-all error handler, how would I do that? It seems to me that I cannot write that test, if But that default catch-all error handler is application behavior, and application behavior should be subject to testing, no? How would you suggest testing that implementation? |
I guess you would set |
If that is the official case, then it seems worth documenting. Do you agree? Reading more about the initial change that I posted above it says the following in 4e71959:
I think I am now understanding a potential difference between a catch-all error handler that is declared using So if you are suggesting that in order to test a declared catch-all error handler, that So I could see a distinction made between a declared catch-all error handler, and an undeclared catch-all error handler. I believe the test on line 102 is testing something undeclared. But the test that I have added is testing something declared. I would offer any of the following suggested options to improve the current situation:
Option 4 is the least intrusive and difficult, so perhaps it would be most attractive. I am happy to open a separate PR to make that sort of change. I will remark that, speaking for myself, even if option 4 would be pursued, I still view the application behavior as inconsistent and confusing. I quite value consistency because I believe it is less cognitive load than having to recall edge-cases for things like While this comment suggests the changes in 4e71959 are the “best of both worlds” I would say it is the quite the opposite, since it introduced inconsistency and arbitrary definition to what |
Thanks for that thorough comment @carlwiedemann. I also like consistency. I think 4. is what we can do short term. For a new major version we could consider the other options I think. I'm interested to hear some thoughts from the rest of @sinatra/sinatras-helpers |
Ok, I opened #1917 for a potential doc update. |
Because the conditional on this line checks for strictly less than instead of less than or equal to, error blocks are unable to catch any thing which is a direct descendant of Exception.
sinatra/lib/sinatra/base.rb
Line 1153 in eee711b
Here's a quick
(untested)example:After visiting
/
, the error block will not be called. If this is by design, then this seems like a strange design decision. If it isn't, then I'd be happy to open a PR for this.The text was updated successfully, but these errors were encountered: