UPDATE: This is now available as an ExceptionNotification plugin.
TobiasLuetke shared this tip on his blog.
Just add this code to your application.rb
protected
def log_error(exception)
super(exception)
begin
ErrorMailer.deliver_snapshot(
exception,
clean_backtrace(exception),
@session.instance_variable_get("@data"),
@params,
@request.env)
rescue => e
logger.error(e)
end
end
If you want this to stick in development mode as well you need to add
def local_request?
false
end
Sample Mailer (generate using script/generate mailer ErrorMailer then edit app/models/error_mailer.rb)
class ErrorMailer < ActionMailer::Base
def snapshot(exception, trace, session, params, env, sent_on = Time.now)
# [nazgum]: Setting the content-type like this did not work for me
#@headers["Content-Type"] = "text/html"
# Setting the content-type like this does:
content_type "text/html"
@recipients = 'target @ domain.tld'
@from = 'Error Mailer <error @ domain.tld>'
@subject = "[Error] exception in #{env['REQUEST_URI']}"
@sent_on = sent_on
@body["exception"] = exception
@body["trace"] = trace
@body["session"] = session
@body["params"] = params
@body["env"] = env
end
end
app/views/error_mailer/snapshot.rhtml:
<style>
<!--
* { font-size: 9pt; font-family: verdana, helvetica, arial, sans-serif; line-height: 1.7em; }
p { margin: 0 }
-->
</style>
<h2>Error report from <%= Time.now %></h2>
<table border="0">
<tr><td>Message</td><td><%= @exception.message %></td></tr>
<tr><td>Location</td><td><%= @env['REQUEST_URI'] %></td></tr>
<tr><td>Action</td><td><%= @params.delete('action') %></td></tr>
<tr><td>Controller</td><td><%= @params.delete('controller') %></td></tr>
<tr><td>Query</td><td><%= @env['QUERY_STRING'] %></td></tr>
<tr><td>Method</td><td><%= @env['REQUEST_METHOD'] %></td></tr>
<tr><td>SSL</td><td><%= @env['SERVER_PORT'].to_i == 443 ? "true" : "false" %></td></tr>
<tr><td>Agent</td><td><%= @env['HTTP_USER_AGENT'] %></td></tr>
<% if @session['user'] -%>
<tr><td>User id</td><td><%= @session['user'].id %></td></tr>
<tr><td>User name</td><td><%= @session['user'].name %></td></tr>
<tr><td>User email</td><td><%= @session['user'].email %></td></tr>
<tr><td>Registered</td><td><%= @session['user'].created_at %></td></tr>
<% end -%>
</table>
<h3>Backtrace</h3>
<div><%= @trace.to_a.join("</p>\n<p>") -%></div>
<h3>Params</h3>
<hr/>
<% for key, val in @params -%>
<p><b><%= key %></b></p>
<p><%= val.to_yaml.to_a.join("</p>\n<p> ") %></p>
<% end if @params -%>
<h3>Session</h3>
<hr/>
<% for key, val in @session -%>
<p><b><%= key %></b></p>
<p><%= val.to_yaml.to_a.join("</p>\n<p> ") %></p>
<% end if @session -%>
<h3>Environment</h3>
<hr/>
<table border="0">
<% for key, val in @env -%>
<tr>
<td>
<small><b><%= key %></b></small>
</td>
<td>
<small><%= val %></small>
</td>
</tr>
<% end if @env -%>
</table>