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.
# 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
# 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
# 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
# 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.
Generated with the Darkfish Rdoc Generator 1.1.6.