Class: Rack::ExceptionNotifier

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/exception_notifier.rb,
lib/rack/exception_notifier/version.rb

Constant Summary collapse

ExcludeBodyKeys =
%w[rack.input rack.request.form_hash rack.request.form_input rack.request.form_vars]
Template =
(<<-'EMAIL').gsub(/^ {4}/, '')
A <%= exception.class.to_s %> occured: <%= exception.to_s %>
<% if _render_body?(env) %>

===================================================================
Request Body:
===================================================================

<%= _extract_body(env).gsub(/^/, '  ') %>
<% end %>

===================================================================
Rack Environment:
===================================================================

  PID:                     <%= $$ %>
  PWD:                     <%= Dir.getwd %>

  <%= env.to_a.
    reject { |key, value| _exclude_env_key?(env, key) }.
    sort { |a, b| a.first <=> b.first }.
    map{ |key, value| "%-25s%p" % [key + ':', value] }.
    join("\n  ") %>

<% if exception.respond_to?(:backtrace) %>
===================================================================
Backtrace:
===================================================================

  <%= exception.backtrace.join("\n  ") %>
<% end %>
EMAIL
VERSION =
'0.3.5'

Instance Method Summary collapse

Constructor Details

#initialize(app, options) ⇒ ExceptionNotifier

Returns a new instance of ExceptionNotifier.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/rack/exception_notifier.rb', line 8

def initialize(app, options)
  default_options = {
    :to => nil,
    :from => ENV['USER'] || 'rack@localhost',
    :subject => '[ERROR] %s',
    :include_body => false
  }
  @app = app
  @options = default_options.merge(options)

  if @options[:to].nil?
    raise ArgumentError.new('to address is required')
  end
end

Instance Method Details

#_body_present?(env) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
# File 'lib/rack/exception_notifier.rb', line 42

def _body_present?(env)
  _extract_body(env, 1)
end

#_exclude_env_key?(env, key) ⇒ Boolean

Returns:

  • (Boolean)


46
47
48
49
50
51
52
# File 'lib/rack/exception_notifier.rb', line 46

def _exclude_env_key?(env, key)
  if _render_body?(env)
    false
  else
    ExcludeBodyKeys.include?(key)
  end
end

#_extract_body(env, length = nil) ⇒ Object



58
59
60
61
62
# File 'lib/rack/exception_notifier.rb', line 58

def _extract_body(env, length = nil)
  io = env['rack.input']
  io.rewind
  io.read(length)
end

#_render_body?(env) ⇒ Boolean

Returns:

  • (Boolean)


54
55
56
# File 'lib/rack/exception_notifier.rb', line 54

def _render_body?(env)
  _body_present?(env) && @options[:include_body]
end

#_send_notification(exception, env) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/rack/exception_notifier.rb', line 30

def _send_notification(exception, env)
  template = ERB.new(Template)

  mail = Mail.new
  mail.to(@options[:to])
  mail.reply_to(@options[:reply_to])
  mail.from(@options[:from])
  mail.subject(@options[:subject] % [exception.to_s])
  mail.body(template.result(binding))
  mail.deliver!
end

#call(env) ⇒ Object



23
24
25
26
27
28
# File 'lib/rack/exception_notifier.rb', line 23

def call(env)
  @app.call(env)
rescue => e
  _send_notification(e, env)
  raise
end