Class Rack::ShowExceptions
In: lib/rack/showexceptions.rb
Parent: Object

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.

Methods

call   new   pretty  

Constants

CONTEXT = 7

Public Class methods

[Source]

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

Public Instance methods

[Source]

    # File lib/rack/showexceptions.rb, line 22
22:     def call(env)
23:       @app.call(env)
24:     rescue StandardError, LoadError, SyntaxError => e
25:       backtrace = pretty(env, e)
26:       [500,
27:        {"Content-Type" => "text/html",
28:         "Content-Length" => backtrace.join.size.to_s},
29:        backtrace]
30:     end

[Source]

    # File lib/rack/showexceptions.rb, line 32
32:     def pretty(env, exception)
33:       req = Rack::Request.new(env)
34:       path = (req.script_name + req.path_info).squeeze("/")
35: 
36:       frames = exception.backtrace.map { |line|
37:         frame = OpenStruct.new
38:         if line =~ /(.*?):(\d+)(:in `(.*)')?/
39:           frame.filename = $1
40:           frame.lineno = $2.to_i
41:           frame.function = $4
42: 
43:           begin
44:             lineno = frame.lineno-1
45:             lines = ::File.readlines(frame.filename)
46:             frame.pre_context_lineno = [lineno-CONTEXT, 0].max
47:             frame.pre_context = lines[frame.pre_context_lineno...lineno]
48:             frame.context_line = lines[lineno].chomp
49:             frame.post_context_lineno = [lineno+CONTEXT, lines.size].min
50:             frame.post_context = lines[lineno+1..frame.post_context_lineno]
51:           rescue
52:           end
53: 
54:           frame
55:         else
56:           nil
57:         end
58:       }.compact
59: 
60:       env["rack.errors"].puts "#{exception.class}: #{exception.message}"
61:       env["rack.errors"].puts exception.backtrace.map { |l| "\t" + l }
62:       env["rack.errors"].flush
63: 
64:       [@template.result(binding)]
65:     end

[Validate]