I want to verify that an exception is being thrown in some function tests by calling get :methodname, :params. I had expected just making this call and then verifying the result is a 500 would be sufficient, but rails is failing the test as soon as the exception is reached in the get. While I figure I could go ahead and wrap the get in a rescue and verify the exception is thrown myself, and would hope there's a better method for doing this.
What's the best way to verify an exception is thrown when using a get in your tests?
You can do:
def test_sommat
assert_raises SomeException do
get :methodname, params
end
end
Related
I'm wondering if rails caches anything in the following case:
Rails.cache.fetch("some_key", expires_in: 1.day) do
service.call # raises exception
[]
end
I'm concerned because if the request inside the Rails.cache.fetch block fails, I want to retry on the next request. Not make the user wait 24HRS to retry.
No. Rails doesn't cache anything if an exception is raised.
Rails Guides says that the return value of the block will be written to the cache.
When a block raises an exception, it doesn't return anything, therefore nothing is cached.
In the production environment configuration I can't seem to find a configuration parameter to tell the server that when an ActiveRecord Class.find() throws an exception, that it should really be an exception. In development mode, it throws an ActiveRecord::RecordNotFound exception, but in production it rescues it and renders a 404. I seem to remember this being something you could turn on/off? I would rather not monkey patch the 404 which is the only solution I have seen so far.
The .find(id) method should be used whenever you want an exception to be thrown if the id cannot be found as described in the documentation. If you don't want an exception to be thrown, you should use .find_by_id(id).
https://github.com/rails/rails/blob/4-0-stable/activerecord/lib/active_record/railtie.rb#L26
adds a mapping
'ActiveRecord::RecordNotFound' => :not_found
asking action_dispatch to rescue 'ActiveRecord::RecordNotFound' with :not_found response.
Doing -
YourAppName::Application.config.action_dispatch.rescue_responses.delete('ActiveRecord::RecordNotFound')
in your initializer might get what you're expecting.
I have an issue with testing error codes. If a record is not found, it raises exception ActiveRecord::RecordNotFound. The thing is, I wanna check if 404 is returned. If I go ahead and just check :
response.status.should == 404
Then this will make the test case fail as RecordNotFound exception is thrown and not caught. If I go ahead and say
expect {<call controller action>}.to raise_error(ActiveRecord::RecordNotFound)
and then check for the status code, then it will fail again, as this catches the exception and the response code is 200.
How should I test if 404 is returned in this kind of case ?
If you don't want checking the exceptions in other examples you can set the following options in your config/environments/test.rb:
config.consider_all_requests_local = false
config.action_dispatch.show_exceptions = true
I'm not sure I understand the specifics well enough to know if this will help you, but check out bypass_rescue as described at https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs/bypass-rescue.
I’m working on this issue: Rails exception notifier in rake tasks
My question: Is there any function/plugin/gem/whatever to setup a generic error/exception handler callback as in PHP with set_error_handler and set_exception_handler?
I need a way to register a callback function used as a catchall outside any begin .. rescue .. end block. For example:
def my_handler *args
# exception processing code here
end
some_magic_method my_handler
raise "An Exception" # this will be handled by my_handler
In PHP this could be achieved with the set_exception_handler function. Is there any such function in Ruby/Rails?
If such feature exists I could solve my previous issue in a simple way.
A Rails-only solution would be fine for my needs.
I don't believe Ruby provides a way to do this, either with exceptions or with throw/catch. In general, doing something this way is a code smell and something to avoid. It makes control flow extremely hard to figure out. I would try to find some other way to approach the problem if at all possible.
If you want to do this in the HTTP Request-handling cycle you may use an around filter in your application controller:
class ApplicationController < ActionController::Base
around_filter do |controller, action|
action.call
rescue ExceptionXPTO
# ... handle the exception ...
end
end
I found a partial solution to my issue which works for the simple case I mentioned in the question. However this can not catch the exception, but it can be useful if someone needs only exception logging or reporting.
#!/usr/bin/env ruby
at_exit do
if $!
puts "Program ended with an exception #{$!.message}"
puts $!.backtrace.join("\n")
# or log the exception here
end
end
loop do
value = rand(3)
puts "Value is #{value}"
break if value == 2
raise "An Exception" if value == 0
end
puts "Program ended normally"
In Rails.
Exception can rescue in controller class but in model class can not.
How to rescue exception in model?
You can do exception handling anywhere in a rails application, as it's part of Ruby, not part of Rails. Wherever you want to catch errors, just wrap it as so:
begin
SomethingElse.doSomething(x, y)
rescue Exception
ErrorLogger.log(Time.now, "Something went wrong!")
end
Please note that you should always "rescue Exception" instead of just "rescue". Just using "rescue" will only catch StandardError, which is a subclass of Exception (meaning something might get through that you don't want to get through).
Also as usual, you can raise an exception by doing:
raise ArgumentError, "Illegal arguments!"
anywhere in your code, be it a model or controller.
Unless I'm mistaken you can use error handling anywhere in Ruby. What are you trying to do?