Disable all html exception rendering in rails

与世无争的帅哥 提交于 2020-01-15 05:59:17

问题


I develop a rest webservice that answers in json. But when some (not all) exceptions are thrown, I am unable to catch them, and rails render an htlm, which is not a valid response for all my clients. The problem comes if an exception is raised in a method called by this catch all:

rescue_from Exception, with: :render_unkown_error

I have to admit, raising an exception in a last chance catch all is very very critical, but I wonder:

Is there a way to totally dismiss all rails response in case of such errors instead of returning an html page containing the stack trace ?

EDIT:

In fact this problems also comes for an undefined property in my controller:

ActionController::RoutingError (undefined local variable or method `truc' for V2::Model3dsController:Class):
app/controllers/v2/model3ds_controller.rb:8:in `<class:Model3dsController>'
app/controllers/v2/model3ds_controller.rb:4:in `<module:V2>'
app/controllers/v2/model3ds_controller.rb:3:in `<top (required)>'

even if I have the following rescue in my base controller:

rescue_from ActionController::RoutingError, with: :render_routing_error

EDIT2:

I have the same kind of problem if the user of my webservice send malformatted parameters to my webservice. Since the execution flow do not pass through my code, the exception is not handled:

Started POST "/users" for XXX.XXX.XXX.XXX at 2013-05-07 11:11:27 +0000
Error occurred while parsing request parameters.
Contents:



MultiJson::LoadError (795: unexpected token at     'url=http%3A%2F%2Ftest.test.com%2Fusers'):
json (1.7.7) lib/json/common.rb:155:in `parse'
json (1.7.7) lib/json/common.rb:155:in `parse'
multi_json (1.7.2) lib/multi_json/adapters/json_common.rb:16:in `load'
multi_json (1.7.2) lib/multi_json/adapter.rb:19:in `load'
multi_json (1.7.2) lib/multi_json.rb:120:in `load'
activesupport (3.2.13) lib/active_support/json/decoding.rb:15:in `decode'
actionpack (3.2.13) lib/action_dispatch/middleware/params_parser.rb:47:in `parse_formatted_parameters'
actionpack (3.2.13) lib/action_dispatch/middleware/params_parser.rb:17:in `call'
actionpack (3.2.13) lib/action_dispatch/middleware/flash.rb:242:in `call'
rack (1.4.5) lib/rack/session/abstract/id.rb:210:in `context'
rack (1.4.5) lib/rack/session/abstract/id.rb:205:in `call'
actionpack (3.2.13) lib/action_dispatch/middleware/cookies.rb:341:in `call'
activerecord (3.2.13) lib/active_record/query_cache.rb:64:in `call'
activerecord (3.2.13) lib/active_record/connection_adapters/abstract/connection_pool.rb:479:in `call'
actionpack (3.2.13) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
activesupport (3.2.13) lib/active_support/callbacks.rb:405:in `_run__3866502263790514870__call__1366634820855087578__callbacks'
activesupport (3.2.13) lib/active_support/callbacks.rb:405:in `__run_callback'
activesupport (3.2.13) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
activesupport (3.2.13) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.2.13) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (3.2.13) lib/action_dispatch/middleware/reloader.rb:65:in `call'
actionpack (3.2.13) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
actionpack (3.2.13) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
actionpack (3.2.13) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
railties (3.2.13) lib/rails/rack/logger.rb:32:in `call_app'
railties (3.2.13) lib/rails/rack/logger.rb:16:in `block in call'
activesupport (3.2.13) lib/active_support/tagged_logging.rb:22:in `tagged'
railties (3.2.13) lib/rails/rack/logger.rb:16:in `call'
actionpack (3.2.13) lib/action_dispatch/middleware/request_id.rb:22:in `call'
rack (1.4.5) lib/rack/methodoverride.rb:21:in `call'
rack (1.4.5) lib/rack/runtime.rb:17:in `call'
activesupport (3.2.13) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
actionpack (3.2.13) lib/action_dispatch/middleware/static.rb:63:in `call'
railties (3.2.13) lib/rails/engine.rb:479:in `call'
railties (3.2.13) lib/rails/application.rb:223:in `call'
railties (3.2.13) lib/rails/railtie/configurable.rb:30:in `method_missing'
thin (1.5.1) lib/thin/connection.rb:81:in `block in pre_process'
thin (1.5.1) lib/thin/connection.rb:79:in `catch'
thin (1.5.1) lib/thin/connection.rb:79:in `pre_process'
eventmachine (1.0.3) lib/eventmachine.rb:1037:in `call'
eventmachine (1.0.3) lib/eventmachine.rb:1037:in `block in spawn_threadpool'


Rendered /home/ubuntu/.rvm/gems/ruby-2.0.0-p0@websrv2.4.0/gems/actionpack-3.2.13/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.8ms)
Rendered /home/ubuntu/.rvm/gems/ruby-2.0.0-p0@websrv2.4.0/gems/actionpack-3.2.13/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.3ms)
Rendered /home/ubuntu/.rvm/gems/ruby-2.0.0-p0@websrv2.4.0/gems/actionpack-3.2.13/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (11.7ms)

回答1:


What you want is exceptions_app.

Rails exceptions_app is basically a configuration option for rails which defaults to the middleware PublicExceptions in ActionDispatch.

This is pretty much what exceptions_app defaults to if none provided:

PublicExceptions

This is the public_exceptions middleware that handles displaying the public 500.html and 400.html

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/public_exceptions.rb

Show Exceptions

This is part of the middleware that shows exceptions on development/production

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L26

Defaults

Here's what it defaults to when you initialize an application

https://github.com/rails/rails/blob/master/railties/lib/rails/application.rb#L391-L393

You can exchange it for an app or route it to your own rails apps like this:

config/application.rb

config.exceptions_app = self.routes

Then in your routes you would match routes like this

routes.rb

match "/500" => "errors#exception"
match "/404" => "errors#not_found"

So you would then have a ErrorsController that would have these actions and handle the response to them.

errors_controller.rb

class ErrorsController < ApiController

  def exception
    render json: {error: "Internal Error"}, status: 500
  end

  def not_found
    render json: {error: "Not Found"}, status: 404
  end
end


来源:https://stackoverflow.com/questions/16108286/disable-all-html-exception-rendering-in-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!