I have the following Sinatra app and I am testing the error block but it doesnt seem to be working i.e I do not see anything in the std output.
require 'sinatra'
error do
puts "----> Failed"
$stdout.print "----> Failed"
end
get "/error" do
raise "OMG"
end
I am using sinatra (1.3.3)
I found this in documentation:
"Sinatra installs special not_found and error handlers when running under the development environment."
What is you environment?
Try with:
ruby test_error.rb -env production
I checked and tested some different cases:
If you have status code error handlers like error 500 {} and you halt 500 you're fine. If you raise somewhere and you have a plain error handler nothing will happen. Same goes for the custom Errors. They will only raise an exception on a missing constant.
I've observed a similar behavior in one of my apps recently. Error handling is generally fine except in development mode. I don't know if this is really intended, but it is not very intuitive IMHO...
@kapso then, do you fixed the problem?
Hi, I looked into this for you with the aim to writing a patch, the issue is that in :development mode raise_errors is set so that Sinatra can do the magic stack trace page, if you want to test the behaviour of your handlers you need to set raise_errors to be false. See the mapped error tests for more information.
Error blocks don't trigger in development mode.
@rkh that's very odd.
No, it's intentional. The idea is that error blocks will hide the issue and you usually don't want to do this in development mode. Do a set :show_exceptions, :after_handler if you want to change that behaviour (see README.md).
Agreed it makes complete sense.
@rkh @JonRowe only when you use exceptions passively for unintended issues IMHO. I tend to use them actively, as a programming mechanism of its own. in that context, it's odd.
EDIT: the difference between "exceptions should not occur, at least I hope so" and "exceptions _will_ occur, handle them"
@blambeau That's fine, rescue them before they get to the output in sinatra, or set :raise_errors, true or set :show_exceptions, :custom_handler like @rkh suggests. Your use case isn't the standard / expected behaviour.
:)
@JonRowe I understand that point of view. I'm not sure to agree with "Your use case isn't the expected behaviour." though.
I can imagine that most people would interpret sinatra's error blocks as a standard try/catch mechanism, mostly because there are very few other exception mechanisms available. Imagine what you would think about ruby changing its behavior wrt rescue clauses according to an environment variable. Wouldn't you think it to be (very) odd?? In web, rack/sinatra is your dev platform and it's recue clauses are odd by default ;-)
@rkh @JonRowe that's basically why I've created Rack::Robustness (https://github.com/blambeau/rack-robustness). Seems much more usable IMHO.
@rkh @JonRowe only when you use exceptions passively for unintended issues IMHO. I tend to use them actively, as a programming mechanism of its own. in that context, it's odd.
EDIT: the difference between "exceptions should not occur, at least I hope so" and "exceptions will occur, handle them"
Yeah, I wouldn't do that and generally think that's not the right approach, but if you do it that way, why not just change that one setting?
I still believe you are the hah, pardon the pun, exception here :) You still have try/catch you still have rescue, this is additional, designed to prevent errors escaping into the rack stack. You can turn it off if you need to.
@JonRowe @rkh I'm the pun exception here, I'm sure (as usual I would add). And I change the setting everytime, and it's ok at first glance.
@rkh I seriously wonder what "the right approach" to exception handling really is. There are very few answers in the SE litterature and most devs simply ignore them completely. try/catch is the (only?) universal mechanism in imperative languages and sinatra departs from it without really providing a serious alternative. If you have a "right approach" to share, I'm much open to learn about it and to co-write a scientific paper with you ;-)
@rkh I found this confusing too... Particularly the fact that not_found is used but error 404 blocks aren't -despite the environment you're in. We found this while adding a few custom pages for our admin in Padrino, see #1149.
Here's a sample app:
require 'sinatra'
set :show_exceptions, :after_handler
get '/hi' do
"Hello World!"
end
get '/force' do
halt 404
end
error 404 do
"I'm a 404"
end
not_found do
"I'm a not_found 404"
end
If you go to any undefined route you get "I'm a not_found 404". If you comment that block out, the "I'm a 404" block never happens which according to the logic described above that's the expected behaviour. Is there a reason why these two don't behave consistently?
Then, when I go to /force, I always get "I'm a 404" despite the fact that the not_found block is before or after the error 404 block. Is this OK?
The default behavior should be to use the custom error block in both production and in development. I can understand the rationale of not wanting to show stack traces in production, but this should be done without affecting the custom error block. IMHO This bothers me as well...