Parent

Class Index [+]

Quicksearch

Rack::ShowExceptions

Rack::ShowExceptions catches all exceptions raised from the app it wraps. It shows a useful backtrace with the sourcefile and clickable context, the whole Rack environment and the request data.

Be careful when you use this on public-facing sites as it could reveal information helpful to attackers.

Constants

CONTEXT

Public Class Methods

new(app) click to toggle source
    # File lib/rack/showexceptions.rb, line 18
18:     def initialize(app)
19:       @app = app
20:       @template = ERB.new(TEMPLATE)
21:     end

Public Instance Methods

call(env) click to toggle source
    # File lib/rack/showexceptions.rb, line 23
23:     def call(env)
24:       @app.call(env)
25:     rescue StandardError, LoadError, SyntaxError => e
26:       exception_string = dump_exception(e)
27: 
28:       env["rack.errors"].puts(exception_string)
29:       env["rack.errors"].flush
30: 
31:       if prefers_plain_text?(env)
32:         content_type = "text/plain"
33:         body = [exception_string]
34:       else
35:         content_type = "text/html"
36:         body = pretty(env, e)
37:       end
38: 
39:       [500,
40:        {"Content-Type" => content_type,
41:         "Content-Length" => Rack::Utils.bytesize(body.join).to_s},
42:        body]
43:     end
dump_exception(exception) click to toggle source
    # File lib/rack/showexceptions.rb, line 49
49:     def dump_exception(exception)
50:       string = "#{exception.class}: #{exception.message}\n"
51:       string << exception.backtrace.map { |l| "\t#{l}" }.join("\n")
52:       string
53:     end
prefers_plain_text?(env) click to toggle source
    # File lib/rack/showexceptions.rb, line 45
45:     def prefers_plain_text?(env)
46:       env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest" && (!env["HTTP_ACCEPT"] || !env["HTTP_ACCEPT"].include?("text/html"))
47:     end
pretty(env, exception) click to toggle source
    # File lib/rack/showexceptions.rb, line 55
55:     def pretty(env, exception)
56:       req = Rack::Request.new(env)
57: 
58:       # This double assignment is to prevent an "unused variable" warning on
59:       # Ruby 1.9.3.  Yes, it is dumb, but I don't like Ruby yelling at me.
60:       path = path = (req.script_name + req.path_info).squeeze("/")
61: 
62:       # This double assignment is to prevent an "unused variable" warning on
63:       # Ruby 1.9.3.  Yes, it is dumb, but I don't like Ruby yelling at me.
64:       frames = frames = exception.backtrace.map { |line|
65:         frame = OpenStruct.new
66:         if line =~ /(.*?):(\d+)(:in `(.*)')?/
67:           frame.filename = $1
68:           frame.lineno = $2.to_i
69:           frame.function = $4
70: 
71:           begin
72:             lineno = frame.lineno-1
73:             lines = ::File.readlines(frame.filename)
74:             frame.pre_context_lineno = [lineno-CONTEXT, 0].max
75:             frame.pre_context = lines[frame.pre_context_lineno...lineno]
76:             frame.context_line = lines[lineno].chomp
77:             frame.post_context_lineno = [lineno+CONTEXT, lines.size].min
78:             frame.post_context = lines[lineno+1..frame.post_context_lineno]
79:           rescue
80:           end
81: 
82:           frame
83:         else
84:           nil
85:         end
86:       }.compact
87: 
88:       [@template.result(binding)]
89:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.