I created a webpage and a XML REST service.
0.
I would like to know how errors are handled in Rails (general).
1.
Let say that a controller does not exists and I would like to redirect a user to a default "Page not found" address (website) or show a default error status code (REST).
2.
What is a best practice for handling controller action errors e.g. when saving but a record is not saved or some param[] field does not exists or else. Usually I use rescue command and I repeat this in every create or update action (would be cool to have some kind of general error handling for that case).
Thank you!
Rails handles 404 and 500 errors out-of-the-box. In development mode you will see detailed error messages. However, in production Rails will use the 404.html and 500.html pages in the public directory.
If the route is not recognised, Rails will return a 404 error.
I generally don't handle errors at the controller level unless they are expected - so I don't wrap everything in begin...rescue. Rails will return the 500 error page if something fatal has occurred. If I expect a particular set of parameters I validate before proceeding and in this case have a redirection or return result to indicate the incomplete parameters.
Related
In our app, we have Sidekiq and have modified the sidekiq.rb file to have it require authentication to view the page.
sidekiq.rb
Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
[user, password] == [ENV['SIDEKIQ_USER'], ENV['SIDEKIQ_PASSWORD']]
end
We want to have an error page set up for whenever the ENVs above are missing it will let us know specifically that the missing ENVs are the issue.
Solution 1: check the Sidekiq web code, open its base controller class and write a before action to render an error page when error happens.
Solution 2: write a conditional route, show the error page when error happens
Solution 3: throw errors in sidekiq.rb, so your server wont startup successfully, you will not need an error page anymore. I think the last one is the best, because this is just internal page to be viewed by few people, and probably only you, its better to find the problem as soon as possible.
My app is just a typical Rails with a Postgresql (actually, Postgres app on OS X). I would like to add exception handling when my Rails app cannot connect to the database and show plain text of connection error for now, instead of a Rails error page (or may be static HTML error page later on).
I've tried adding exception below to the application_controller.rb.
# from app/controllers/application_controllers.rb
-------------------------------------------------
rescue_from PG::ConnectionBad, with: :database_connection_error
def :database_connection_error
render plain: "Could not connect to the Database"
end
(code ommited)
but it's not rendering plain text. (I also use this exception snippet on the other controllers. It's working but it's handling a different exception, e.g. I use it to handling ActiveRecord::RecordNotFound error)
Is there any way to handle a PG::ConnectionBad or point out what I am doing wrong here?
Thanks in advance.
I just launched a completely rebuilt in rails website and am using New Relic for error monitoring. I've been getting a lot of errors and alerts for what I'm guessing is people using bookmarks for pages/paths that no longer exist and possibly some hot linking.
What is the best way to resolve this situation so that I stop getting the alerts?
How about ignoring those errors?
ignore_errors - A comma separated list of Exception classes which will
be ignored
In addition, the error collector can be customized programmatically
for more control over filtering. In your application initialization,
you can register a block with the Agent to be called when an error is
detected. The block should return the error to record, or nil if the
error is to be ignored. For example:
config.after_initialize do
::NewRelic::Agent.ignore_error_filter do |error|
if error.message =~ /gateway down/
nil
elsif
error.class.name == "InvalidLicenseException"
StandardError.new "We should never see this..."
else
error
end
end
end
(source)
I've got problem with migrating rails 2.x -> 3.2.13
At some point, after fixing a few things, I get Completed 500 Internal Server Error in 76ms without any traceback.
development.rb
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
Why there is no traceback and how to fix this?
you probably solved it but I wanted to share my couple of hours debugging about this issue as it can be very annoying. In short, I was having the same problem - 500 internal server error without any log of the exception thrown. It was happening only for exceptions thrown in the action view templates - any ActionView::Template::Error exception. For example, missing partial, invalid route.
My specific problem was using this ruby statistics module:
http://derrick.pallas.us/ruby-stats/
directly in the initializers directory which works great in rails 2.x. It defined Array.sum method which is already defined in rails 3 under Enumerable.sum. The problem with the redefine is that Array.sum no longer works with arrays of strings which is what rails was trying to do with ActionView::Template::Error.source_extract method - when trying to extract the source of the error in template, it uses the Enumerable.sum method which is redefined in a wrong way. Thus, another exception happened TypeError: cannot convert String into Fixnum and the original exception was not logged, neither was the new one. I had to do a backtrace and go through many of the internal calls to see where is the issue.
So, for everyone not seeing the actual exceptions thrown in your ActionView templates, check if you have not redefined a rails method that is used internally in rails.
I have a view named new.html.erb with the following code:
<%= some_non_existent_thing.imaginary_method %>
Now, I only see one simple 500 error page, like that:
500 Internal Server Error
If you are the administrator of this website, then please read this web application's log file and/or the web server's log file to find out what went wrong.
Shouldn't I see a pretty formatted page with some information about the exception?
I'm not sure I miss something here, but I believe rails used to show the full error page in development environment when there is something wrong in the view.
Are you sure that you are running the development environment? Check that RAILS_ENV=development or that you are running rails server -e development.
Then check your development.rb file, you should have the following line in it
config.consider_all_requests_local = true
If you happen to have an exception inside an exception, Rails has a middleware that catches it and returns a FAILSAFE_RESPONSE with the following copy:
500 Internal Server Error
If you are the administrator of this website, then please read this web application's log file and/or the web server's log file to find out what went wrong.
A nice way to troubleshoot this is to compare your custom error code with the sample code provided in the Rails 4.2.0 guides.
I'm pointing to that particular version because that whole section was removed in the Rails 5.0.0 guides.
Ideally, you should keep your error views, layout, and controller as free of logic as possible, to avoid running into this issue.
Firstly, as Anton mentions in the answer below, confirm that your config/environments/development.rb has:
config.consider_all_requests_local = true
and that you are running the server in development mode.
I had ensured the above and still observed the error.
This happened in my case, because my logger had some errors. I was using a custom log formatter, which used the String#% method to format the log. % seems to be very buggy and leads to all these weird errors. I figured this one out by adding a debugger line to the controller method and stepping through into the implicit render function call. It hit the bug and reported it as a malformed format string error.
This was the log formatter I was using before, which caused the bugs [I had added it to an initializer file]:
class Logger::SimpleFormatter
def call(severity, time, progname, msg)
"%-7s #{msg}\n" % severity
end
end
These modifications fixed the bug:
class Logger::SimpleFormatter
def call(severity, time, progname, msg)
severity_prefix = "[#{severity}]".ljust(7)
"#{severity_prefix} #{msg}\n"
end
end
This happens if the code is not compilable, for example if you have an if statement missing an end.