Configuring proper sequence of Rack middlewares ...

I am running into a situation where I can’t ensure the proper sequence of Rack middlewares. I have two middlewares in my Rails 3.0.9 stack:

1- ExceptionNotifier

2- ActionDispatch::ShowExceptions

The first one is a gem that notifies me (via email) of any unhandled exception thrown by my app. The second one is to handle the display of error pages. The call methods of these two are straightforward. The first one calls its predecessor and catches resulting exception, sends email and re-raises the same exception. The second one just enhances already available functionality in Rails to render properly formatted pages. The second one does not raise any exception and thus renders the response and everything is all right.

In an initializer, I have a code (link to gist) that inserts the 1st one before the 2nd one.

But in reality, ActionDispatch::ShowException is always called first and when I get an exceptional condition, the properly formatted error pages are displayed, but email is never sent because the ExceptionNotifier is never called.

Does that make sense? Anybody has any comment about how I can make it do the right thing? (Call ExceptionNotifier first and ShowExceptions later).

Regards,

Kedar

PS: output of rake middleware with this setup:

use ActionDispatch::Static

use Rack::Lock

use ActiveSupport::Cache::Strategy::LocalCache

use Rack::Runtime

use Rails::Rack::Logger

use ExceptionNotifier

use ActionDispatch::ShowExceptions

use ActionDispatch::ShowExceptions

use ActionDispatch::RemoteIp

use Rack::Sendfile

use ActionDispatch::Callbacks

use ActiveRecord::ConnectionAdapters::ConnectionManagement

use ActiveRecord::QueryCache

use ActionDispatch::Cookies

use ActionDispatch::Session::CookieStore

use ActionDispatch::Flash

use ActionDispatch::ParamsParser

use Rack::MethodOverride

use ActionDispatch::Head

use ActionDispatch::BestStandardsSupport

use OAuth2::Provider::Rack::Middleware

use OmniAuth::Builder

run MyApp::Application.routes

The best way to visualize the process here is to imagine the request comes in at the top of the middleware stack (AD::Static here) and is passed down to successive middlewares until it generates a response. The response then flows back up the stack until it gets to the top and is handed to the web server for delivery to the user.

Short story shorter, you need to put them in the opposite order - ShowExceptions is rescuing the exception so ExceptionNotifier never sees it.

–Matt Jones

The best way to visualize the process here is to imagine the request comes in at the top of the middleware stack (AD::Static here) and is passed down to successive middlewares until it generates a response. The response then flows back up the stack until it gets to the top and is handed to the web server for delivery to the user.

Short story shorter, you need to put them in the opposite order - ShowExceptions is rescuing the exception so ExceptionNotifier never sees it.

Thank you, Matt Jones.

I changed the sequence so that ExceptionNotifier middleware is below the ShowExceptions middleware in the stack (as reported by rake middleware).

In this case however, I am not seeing the desired effect. Is it because ShowExceptions::render_exeption_with_template, as written, actually renders the response (the formatted error page) and does not re-raise the exception? Should I rewrite ShowExceptions::render_exeption_with_template to re-raise the exception in case of certain errors (e.g. 500 and not 404)?

Regards,

Kedar