In Rails 2.3.x, you can override render_optional_error_file like so:
# ApplicationController.rb
protected
def render_optional_error_file(status_code)
render :template => "errors/500", :status => 500, :layout => 'application'
end
However, Rails 3 no longer has render_optional_error_file. Instead, you need to override rescue_action_in_public, which you can do like so:
# config/initializers/error_page.rb
module ActionDispatch
class ShowExceptions
protected
def rescue_action_in_public(exception)
status = status_code(exception).to_s
template = ActionView::Base.new(["#{Rails.root}/app/views"])
if ["404"].include?(status)
file = "/errors/404.html.erb"
else
file = "/errors/500.html.erb"
end
body = template.render(:file => file)
render(status, body)
end
end
end
This works, but does not use the application's layout. However, if you specify the layout path like so:
body = template.render(:file => file, :layout => "layouts/application") # line 15
You get an Error during failsafe response: ActionView::Template::Error.
Line 4 of application.html.erb:4 is:
<%= stylesheet_link_tag "app", "jquery-ui", "jquery.fancybox", :cache => "all" %>
Whatever ActionView normally uses to render templates isn't getting loaded.
The stack trace is:
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:794:in `join'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:794:in `rails_asset_id'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:817:in `rewrite_asset_path'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:746:in `compute_public_path'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:424:in `path_to_stylesheet'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:875:in `ensure_stylesheet_sources!'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:874:in `each'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:874:in `ensure_stylesheet_sources!'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:512:in `stylesheet_link_tag'
/data/sites/fundraisers-stage/releases/20110316194843/app/views/layouts/application.html.erb:4:in `_app_views_layouts_application_html_erb___19482063_70294907435920_0'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/template.rb:135:in `send'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/template.rb:135:in `render'
/var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications.rb:54:in `instrument'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/template.rb:127:in `render'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/layouts.rb:80:in `_render_layout'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/rendering.rb:62:in `_render_template'
/var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications.rb:52:in `instrument'
/var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications.rb:52:in `instrument'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/rendering.rb:56:in `_render_template'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/rendering.rb:26:in `render'
/data/sites/fundraisers-stage/releases/20110316194843/config/initializers/error_pages.rb:15:in `rescue_action_in_public'
In rails 3.2, it's easier than that:
Add this to config/application.rb:
config.exceptions_app = self.routes
That causes errors to be routed via the router. Then you just add to config/routes.rb:
match "/404", :to => "errors#not_found"
I got this info from item #3 on the blog post "My five favorite hidden features in Rails 3.2" by By José Valim.
I would suggest using rescue_from instead. You would just rescue from specific errors rather than overriding rescue_action_in_public. This is especially useful when dealing with user-defined errors or controller-specific errors.
# ApplicationController
rescue_from ActionController::RoutingError, :with => :render_404
rescue_from ActionController::UnknownAction, :with => :render_404
rescue_from ActiveRecord::RecordNotFound, :with => :render_404
rescue_from MyApp::CustomError, :with => :custom_error_resolution
def render_404
if /(jpe?g|png|gif)/i === request.path
render :text => "404 Not Found", :status => 404
else
render :template => "shared/404", :layout => 'application', :status => 404
end
end
# UsersController
rescue_from MyApp::SomeReallySpecificUserError, :with => :user_controller_resolution
http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html
The exception notifier has a method called notify_about_exception to initiate the error notification on demand.
class ApplicationController < ActionController::Base
include ExceptionNotification::Notifiable
rescue_from Exception, :with => :render_all_errors
def render_all_errors(e)
log_error(e) # log the error
notify_about_exception(e) # send the error notification
# now handle the page
if e.is_a?(ActionController::RoutingError)
render_404(e)
else
render_other_error(e)
end
end
def render_404_error(e)
# your code
end
def render_other_error(e)
# your code
end
end
I have also faced such problem. The problem is because of attachment_fu gem or plugin. Just uninstall it and use any other plugin or gem will solve your problem.
Related
First at all, I have read:
Cookie overflow in rails application?
And this is not the problem that I'm facing.
I'm working with:
gem "rails", "~> 3.2.11"
and
ruby 1.9.3-p125
I'm trying to process a search, and when the search is tooooooo big I get this error:
ActionDispatch::Cookies::CookieOverflow
I would like to rescue_form this error in the ApplicationController but it seems that is not working for me:
rescue_from ActionDispatch::Cookies::CookieOverflow :with => :render_404
where:
def render_404
respond_to do |r|
r.html { render :template => "something/404", :status => 404}
r.all { render :nothing => true, :status => 404 }
end
true
end
any help is going to be well received.
rescue_from ActionDispatch::Cookies::CookieOverflow :with => :render_404
you are missing comma (,) in arguments , according to docs
with correc syntax
rescue_from ActionDispatch::Cookies::CookieOverflow, with: :render_404
rescue_from receives a series of exception classes or class names, and
a trailing :with option with the name of a method
see more:
http://api.rubyonrails.org/v5.0/classes/ActiveSupport/Rescuable/ClassMethods.html
I am working on a Rails app. In my app, if I enter a custom route manually in the address bar/ as URL which is not present in config/routes.rb, it will show up the below given error message.
Routing Error
No route matches "/clientImage/blablahblah"
I want this to be redirected to a proper display for all the wrong routes given by the user either intentionally/unintentionally. Any help would be greatly appreciated.
When someone enters unsupported url Rails will raise ActionController::RoutingError. You can rescue this error and render 404 Not Found html.
Rails provides some special function called rescue_from for this purpose.
class ApplicationController < ActionController::Base
rescue_from ActionController::RoutingError, :with => :render_not_found
rescue_from StandardError, :with => :render_server_error
protected
def render_not_found
render "shared/404", :status => 404
end
def render_server_error
render "shared/500", :status => 500
end
end
Put your 404.html, 500.html in app/views/shared
Yourapp::Application.routes.draw do
#Last route in routes.rb
match '*a', :to => 'errors#routing'
end
The "a" is actually a parameter in the Rails 3 Route Globbing technique. For example, if your url was /this-url-does-not-exist, then params[:a] equals "/this-url-does-not-exist". So be as creative as you'd like handling that rogue route.
In app/controllers/errors_controller.rb
class ErrorsController < ApplicationController
def routing
render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
end
end
In Rails 2.3.x, you can override render_optional_error_file like so:
# ApplicationController.rb
protected
def render_optional_error_file(status_code)
render :template => "errors/500", :status => 500, :layout => 'application'
end
However, Rails 3 no longer has render_optional_error_file. Instead, you need to override rescue_action_in_public, which you can do like so:
# config/initializers/error_page.rb
module ActionDispatch
class ShowExceptions
protected
def rescue_action_in_public(exception)
status = status_code(exception).to_s
template = ActionView::Base.new(["#{Rails.root}/app/views"])
if ["404"].include?(status)
file = "/errors/404.html.erb"
else
file = "/errors/500.html.erb"
end
body = template.render(:file => file)
render(status, body)
end
end
end
This works, but does not use the application's layout. However, if you specify the layout path like so:
body = template.render(:file => file, :layout => "layouts/application") # line 15
You get an Error during failsafe response: ActionView::Template::Error.
Line 4 of application.html.erb:4 is:
<%= stylesheet_link_tag "app", "jquery-ui", "jquery.fancybox", :cache => "all" %>
Whatever ActionView normally uses to render templates isn't getting loaded.
The stack trace is:
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:794:in `join'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:794:in `rails_asset_id'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:817:in `rewrite_asset_path'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:746:in `compute_public_path'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:424:in `path_to_stylesheet'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:875:in `ensure_stylesheet_sources!'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:874:in `each'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:874:in `ensure_stylesheet_sources!'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:512:in `stylesheet_link_tag'
/data/sites/fundraisers-stage/releases/20110316194843/app/views/layouts/application.html.erb:4:in `_app_views_layouts_application_html_erb___19482063_70294907435920_0'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/template.rb:135:in `send'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/template.rb:135:in `render'
/var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications.rb:54:in `instrument'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/template.rb:127:in `render'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/layouts.rb:80:in `_render_layout'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/rendering.rb:62:in `_render_template'
/var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications.rb:52:in `instrument'
/var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications.rb:52:in `instrument'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/rendering.rb:56:in `_render_template'
/var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/rendering.rb:26:in `render'
/data/sites/fundraisers-stage/releases/20110316194843/config/initializers/error_pages.rb:15:in `rescue_action_in_public'
In rails 3.2, it's easier than that:
Add this to config/application.rb:
config.exceptions_app = self.routes
That causes errors to be routed via the router. Then you just add to config/routes.rb:
match "/404", :to => "errors#not_found"
I got this info from item #3 on the blog post "My five favorite hidden features in Rails 3.2" by By José Valim.
I would suggest using rescue_from instead. You would just rescue from specific errors rather than overriding rescue_action_in_public. This is especially useful when dealing with user-defined errors or controller-specific errors.
# ApplicationController
rescue_from ActionController::RoutingError, :with => :render_404
rescue_from ActionController::UnknownAction, :with => :render_404
rescue_from ActiveRecord::RecordNotFound, :with => :render_404
rescue_from MyApp::CustomError, :with => :custom_error_resolution
def render_404
if /(jpe?g|png|gif)/i === request.path
render :text => "404 Not Found", :status => 404
else
render :template => "shared/404", :layout => 'application', :status => 404
end
end
# UsersController
rescue_from MyApp::SomeReallySpecificUserError, :with => :user_controller_resolution
http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html
The exception notifier has a method called notify_about_exception to initiate the error notification on demand.
class ApplicationController < ActionController::Base
include ExceptionNotification::Notifiable
rescue_from Exception, :with => :render_all_errors
def render_all_errors(e)
log_error(e) # log the error
notify_about_exception(e) # send the error notification
# now handle the page
if e.is_a?(ActionController::RoutingError)
render_404(e)
else
render_other_error(e)
end
end
def render_404_error(e)
# your code
end
def render_other_error(e)
# your code
end
end
I have also faced such problem. The problem is because of attachment_fu gem or plugin. Just uninstall it and use any other plugin or gem will solve your problem.
I am trying to setup a custom error page in my website. I am following the guidelines atPerfectLine Blog.
It works in the case where the controller exists, but the id does not exist. For example, I have a blog controller and id 4 does not exist. It shows the custom error page
But it does not exist in the case, where controller itself does not exist. For example, if I type some random controller with a numeric id does not gets caught by the methods I have setup in the application controller to re-route the custom error pages. In this case, I get an
ActionController::RoutingError (No route matches "/randomcontrollername"):
in the terminal and the default error page that comes with rails.
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
unless Rails.application.config.consider_all_requests_local
rescue_from Exception, :with => :render_error
rescue_from ActiveRecord::RecordNotFound, :with => :render_not_found
rescue_from ActionController::RoutingError, :with => :render_not_found
rescue_from ActionController::UnknownController, :with => :render_not_found
rescue_from ActionController::UnknownAction, :with => :render_not_found
end
private
def render_not_found(exception)
render :template => "/error/404.html.erb", :status => 404
end
def render_error(exception)
render :template => "/error/500.html.erb", :status => 500
end
end
Could you please help me. Thanks.
You can do that with route globbing in rails, It lets you match any action to any part of a route using wildcards.
To catch all remaining routes, just define a low priority route mapping as the last route in config/routes.rb:
In Rails 3:
match "*path" => 'error#handle404'
In Rails 2:
map.connect "*path", :controller => 'error', :action => 'handle404'
params[:path] will contain the matching part.
If you don't need dynamic error pages, just edit public/404.html and public/505.html. If you do, see Reza.mp's answer.
I am working on a RoR website and would like to handle server errors (400, 404, 500, etc.) individually. Also, since the website is dynamic I would like to handle the errors within the rails environment rather than at the server level.
An example of what I would like to do could be to present the user with optional material or a search bar when she bumps into a page or template that will not load or simply does not exist.
So, I did a bit of reading and I think that using the rescue_from exception handler is the way to go in my case. (Would be more than happy to hear if any of you have a different opinion).
I have a simple working prototype (see code below) up and running, however, I get an error when I include the following exception handler to the code:
rescue_from ActionController::MissingTemplate, :with => :not_found #404
Now, I can't see that I have a spelling error and I have seen this line in code posted on the web. However, when I include it I get the following routing error:
Routing Error No route matches "/errorhandle" with {:method=>:get}
I am working on rails 2.3.5, perhaps that has got something to do with it?
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
protect_from_forgery #See ActionController::RequestForgeryProtection for details
#ActiveRecord exceptions
rescue_from ActiveRecord::RecordNotFound, :with => :not_found #400
#ActiveResource exceptions
rescue_from ActiveResource::ResourceNotFound, :with => :not_found #404
#ActionView exceptions
rescue_from ActionView::TemplateError, :with => :not_found #500
#ActionController exceptions
rescue_from ActionController::RoutingError, :with => :not_found #404
rescue_from ActionController::UnknownController, :with => :not_found #404
rescue_from ActionController::MethodNotAllowed, :with => :not_found #405
rescue_from ActionController::InvalidAuthenticityToken, :with => :not_found #405
rescue_from ActionController::UnknownAction, :with => :not_found #501
# This particular exception causes all the rest to fail.... why?
# rescue_from ActionController::MissingTemplate, :with => :not_found #404
protected
def not_found
render :text => "Error", :status => 404
end
# Scrub sensitive parameters from your log
# filter_parameter_logging :password
end
Take a quick look at these:
http://www.ruby-forum.com/topic/47898
http://henrik.nyh.se/2008/09/404-invalid-rails-format
In particular, a post in the first link:
You can't use a regular 'rescue' keyword to rescue MissingTemplate
exception.
Use rescue_action instead, for example:
def rescue_action(exception)
if ::ActionController::MissingTemplate === exception
render :text => 'rescued'
else
super
end
end
Kent.