A skeleton web application configured to use Sinatra and ActiveRecord
at master 100 lines 2.2 kB view raw
1module Rack 2 class ExceptionMailer 3 def initialize(app) 4 @app = app 5 end 6 7 def call(env) 8 return @app.call(env) 9 10 rescue => e 11 unless boring?(e) 12 email e, env 13 end 14 15 return [ 16 500, 17 { "Content-Type" => "text/html" }, 18 [ "<html><body><h1>Internal Server Error</h1><p>:(</p></body></html>" ], 19 ] 20 end 21 22 private 23 def boring?(exception) 24 [ 25 EOFError, 26 Rack::QueryParser::InvalidParameterError, 27 ].include?(exception.class) 28 end 29 30 def email(exception, env) 31 b = body(exception, env) 32 33 if App.exception_recipients.any? 34 Pony.mail( 35 :to => App.exception_recipients, 36 :subject => "[#{App.name}] #{exception.class} exception " << 37 "(#{exception.message[0, 50]})", 38 :body => b 39 ) 40 end 41 42 STDERR.puts b 43 end 44 45 def first_app_call(exception) 46 exception.backtrace.each do |l| 47 if (rp = relative_path(l)).match(/^app\//) 48 return rp 49 end 50 end 51 52 relative_path(exception.backtrace[0]) 53 end 54 55 def body(exception, env) 56 o = [ 57 "#{exception.class} exception:", 58 "", 59 " #{exception.message}", 60 "", 61 first_app_call(exception), 62 "", 63 "Request:", 64 "-------------------------------", 65 "", 66 " URL: #{env["REQUEST_URI"]}", 67 " Method: #{env["REQUEST_METHOD"]}", 68 " IP address: #{env["REMOTE_ADDR"]}", 69 " User agent: #{env["HTTP_USER_AGENT"]}", 70 "", 71 "Parameters:", 72 "-------------------------------", 73 ] 74 75 App.filter_parameters(env["sinatra.error.params"] || {}).each do |k,v| 76 o.push " #{k}: #{v}" 77 end 78 79 o += [ 80 "", 81 "Backtrace:", 82 "-------------------------------", 83 ] 84 85 exception.backtrace.each do |l| 86 o.push " #{relative_path(l)}" 87 end 88 89 o.join("\n") 90 end 91 92 def relative_path(path) 93 if path[0, App.root.length] == App.root 94 path[App.root.length .. -1].gsub(/^\//, "") 95 else 96 path 97 end 98 end 99 end 100end