title: How to rescue ActionDispatch::ParamsParser::ParseError and return custom API error in rails 5?
body: <p>Whenever sending malformed JSON against my API-only Rails 5.x application, I get an exception and Rails is returning the entire stack trace as JSON. Obviously I'd like to respond with a nicely, custom, formatted error.</p>
  
  <pre><code>=&gt; Booting Puma
  =&gt; Rails 5.0.0.1 application starting in development on http://localhost:3000
  =&gt; Run `rails server -h` for more startup options
  Puma starting in single mode...
  * Version 3.6.0 (ruby 2.3.0-p0), codename: Sleepy Sunday Serenity
  * Min threads: 5, max threads: 5
  * Environment: development
  * Listening on tcp://localhost:3000
  Use Ctrl-C to stop
  Started POST "/api/v1/identities/" for ::1 at 2016-10-26 18:42:32 +0200
    ActiveRecord::SchemaMigration Load (0.3ms)  SELECT "schema_migrations".* FROM "schema_migrations"
  Error occurred while parsing request parameters.
  Contents:
  
  {
      "whatever": "ewewgewewtwe"
      "malformed_json": ";
  }
  
  ActionDispatch::ParamsParser::ParseError (822: unexpected token at '{
      "whatever": "ewewgewewtwe"
      "malformed_json": ";
  }'):
  
  actionpack (5.0.0.1) lib/action_dispatch/http/parameters.rb:71:in `rescue in parse_formatted_parameters'
  actionpack (5.0.0.1) lib/action_dispatch/http/parameters.rb:65:in `parse_formatted_parameters'
  actionpack (5.0.0.1) lib/action_dispatch/http/request.rb:366:in `block in POST'
  rack (2.0.1) lib/rack/request.rb:57:in `fetch'
  rack (2.0.1) lib/rack/request.rb:57:in `fetch_header'
  actionpack (5.0.0.1) lib/action_dispatch/http/request.rb:365:in `POST'
  actionpack (5.0.0.1) lib/action_controller/metal/params_wrapper.rb:282:in `_wrapper_enabled?'
  actionpack (5.0.0.1) lib/action_controller/metal/params_wrapper.rb:231:in `process_action'
  activerecord (5.0.0.1) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (5.0.0.1) lib/abstract_controller/base.rb:126:in `process'
  actionpack (5.0.0.1) lib/action_controller/metal.rb:190:in `dispatch'
  actionpack (5.0.0.1) lib/action_controller/metal.rb:262:in `dispatch'
  actionpack (5.0.0.1) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'
  actionpack (5.0.0.1) lib/action_dispatch/routing/route_set.rb:32:in `serve'
  actionpack (5.0.0.1) lib/action_dispatch/journey/router.rb:39:in `block in serve'
  actionpack (5.0.0.1) lib/action_dispatch/journey/router.rb:26:in `each'
  actionpack (5.0.0.1) lib/action_dispatch/journey/router.rb:26:in `serve'
  actionpack (5.0.0.1) lib/action_dispatch/routing/route_set.rb:725:in `call'
  rack (2.0.1) lib/rack/etag.rb:25:in `call'
  rack (2.0.1) lib/rack/conditional_get.rb:38:in `call'
  rack (2.0.1) lib/rack/head.rb:12:in `call'
  activerecord (5.0.0.1) lib/active_record/migration.rb:552:in `call'
  actionpack (5.0.0.1) lib/action_dispatch/middleware/callbacks.rb:38:in `block in call'
  activesupport (5.0.0.1) lib/active_support/callbacks.rb:97:in `__run_callbacks__'
  activesupport (5.0.0.1) lib/active_support/callbacks.rb:750:in `_run_call_callbacks'
  activesupport (5.0.0.1) lib/active_support/callbacks.rb:90:in `run_callbacks'
  actionpack (5.0.0.1) lib/action_dispatch/middleware/callbacks.rb:36:in `call'
  actionpack (5.0.0.1) lib/action_dispatch/middleware/executor.rb:12:in `call'
  actionpack (5.0.0.1) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
  actionpack (5.0.0.1) lib/action_dispatch/middleware/debug_exceptions.rb:49:in `call'
  actionpack (5.0.0.1) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
  railties (5.0.0.1) lib/rails/rack/logger.rb:36:in `call_app'
  railties (5.0.0.1) lib/rails/rack/logger.rb:24:in `block in call'
  activesupport (5.0.0.1) lib/active_support/tagged_logging.rb:70:in `block in tagged'
  activesupport (5.0.0.1) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (5.0.0.1) lib/active_support/tagged_logging.rb:70:in `tagged'
  railties (5.0.0.1) lib/rails/rack/logger.rb:24:in `call'
  actionpack (5.0.0.1) lib/action_dispatch/middleware/request_id.rb:24:in `call'
  rack (2.0.1) lib/rack/runtime.rb:22:in `call'
  activesupport (5.0.0.1) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
  actionpack (5.0.0.1) lib/action_dispatch/middleware/executor.rb:12:in `call'
  actionpack (5.0.0.1) lib/action_dispatch/middleware/static.rb:136:in `call'
  rack (2.0.1) lib/rack/sendfile.rb:111:in `call'
  railties (5.0.0.1) lib/rails/engine.rb:522:in `call'
  puma (3.6.0) lib/puma/configuration.rb:225:in `call'
  puma (3.6.0) lib/puma/server.rb:578:in `handle_request'
  puma (3.6.0) lib/puma/server.rb:415:in `process_client'
  puma (3.6.0) lib/puma/server.rb:275:in `block in run'
  puma (3.6.0) lib/puma/thread_pool.rb:116:in `block in spawn_thread'
  </code></pre>
  
  <p>Previously I think it was possible to add a middleware and handle the exception as following: </p>
  
  <pre><code># in config/application.rb
  
  config.middleware.insert_before(ActionDispatch::ParamsError,'BadRequestError')
  
  # middleware
  
  class BadRequestError
      def initialize(app)
          @app = app
      end
  
      def call(env)
          begin
              @app.call(env)
          rescue ActionDispatch::ParamsParser::ParseError
              Api::ApiController.action(:raise_bad_request).call(env)
          end
      end
  end
  </code></pre>
  
  <p>However it seems that the middleware <code>ActionDispatch::ParamsError</code> was removed from Rails 5 ; </p>
  
  <p>I also tried with other middlewares (e.g. ActionDispatch::ShowExceptions), rescuing different errors, but my <code>raise_bad_request</code> action is somehow never called. </p>
  
  <p>Am I missing something, doing something wrong, or is there another way of doing that with Rails 5? </p>
  
  <p>Thanks! </p>