We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.
Oh, excellent. Updated the post and gave you credit. Thank you! Tried with consider_all_requests_local but didn't realize I needed that other one too.
No problem. Glad it worked :]
Great blog btw. I've learned some new things from you in various posts you've put up. Good stuff!
Sadly, I just restored the old test code :/ Turns out this worked fine when run as a standalone test, but not as part of a test suite. I suspect once some other test has started a server without that config, a later test can't change it. Maybe due to Spring's preloading?
Glad you like the blog! Thanks for telling me.
I had the same problem -- the spec only passed when run outside of the suite (rails 4.1.5).
action_dispatch.show_exceptions gets copied and cached in Rails.application.env_config, so even if you change Rails.application.config.action_dispatch.show_exceptions in a before block, the value isn't what you expect when it's used in ActionDispatch::DebugExceptions.
My solution was to intercept the env_config method:
method = Rails.application.method(:env_config)
expect(Rails.application).to receive(:env_config).with do
method.call.merge(
'action_dispatch.show_exceptions' => true,
'action_dispatch.show_detailed_exceptions' => false
)
end
I also used "expect_any_instance_of(ActionDispatch::DebugExceptions).to receive(:log_error)" to quiet the printing of the stack trace in specs.
Thanks for sharing this. I suggest to add .(no_args()) after (:env_config).with to prevent an error with latest rspec
updated code snippet:
# errors_spec.rb
context '404' do
before do
method = Rails.application.method(:env_config)
expect(Rails.application).to receive(:env_config).with(no_args()) do
method.call.merge(
'action_dispatch.show_exceptions' => true,
'action_dispatch.show_detailed_exceptions' => false
)
end
end
it 'returns appropriate status code and content' do
visit '/not-a-real-page'
expect(page.status_code).to eql 404
expect(page).to have_content '404 - File Not Found'
end
end
expect(Rails.application).to receive(:env_config).with(no_args()) doOh man it's times like this you realize you've been coding for way too many hours and need to go to bed. Duh. Thanks.
you're welcome!
Since RSpec 3.1 you can use and_wrap_original which looks like:
allow(Rails.application).to receive(:env_config).with(no_args()).and_wrap_original do |m, *args|
m.call.merge(
'action_dispatch.show_exceptions' => true,
'action_dispatch.show_detailed_exceptions' => false
)
end
Thanks for sharing. You saved me many hours reading through Rails code. I also had to add 'consider_all_requests_local' => false because I'm testing if my custom error pages actually work.
Just found the solution you posted via another blog. Thanks it was a great help.
Thanks for sharing, any ideas how to test CustomPublicExceptions class with RSpec?
That class on its own? I'm pretty happy with just an integration test as described in the post.
The CustomPublicExceptions class doesn't do very complex logic, so unit testing it wouldn't add much in my opinion, and would probably be tricky.
Yes, tricky indeed, thats why I asked.
Why don't we just edit the public\assets\404.html page? Is that simpler?
It's definitely simpler, and there's less risk that some sneaky error takes out your error page, too, but if you want to reuse your Rails layouts or use dynamic content like Rails translations, editing the HTML page is not an option.
what? if we want to expose error page for 500 error
What's the difference between your approach, and this, seemingly simpler one?
http://easyactiverecord.com...
Along with the routes, all you need to do is tell the app to handle exceptions via the router:
module DevArcadenomadCom
class Application < Rails::Application
config.exceptions_app = self.routes
end
end
As the intro says:
This is what I did to get a custom 404 error page on Rails 4, without replacing the default 500 and 422 error pages.
There are other solutions where you just use the router as the exceptions app, but then you have to handle those other errors as well.
I don't remember anymore why I wanted a solution with those constraints. I'm sure the simpler solution is better in many cases.
Thanks! Great article. Liked the design of your site, too.
Thank you, Patricio! :)
This worked perfectly for me. No edits needed at all. Thanks so much!
this is a great solution to this.. thanks works like a charm
Thanks so much!!!
how, if I want to call the page can not be found on another controller to provide the conditions?
if no_session.nil?
# how to call 404 page
false
else
true
end
I'm not sure if I understand the question, but maybe this helps: http://thepugautomatic.com/...
thxs sir
this works great, thanks a lot Henrik!
thank you, few years passed and there are a lot of modifications of these basic 2 approaches:
1) with just exceptions_app + routes:
class Application < Rails::Application
config.exceptions_app = self.routes
end
2) similar to your version with errors handling mechanism
But still love yours the most!
Aw, thank you :)
Try this to test the 404 page with a bad URL: