module Roda::RodaPlugins::ExceptionPage::InstanceMethods
def exception_page(exception, opts=OPTS)
Designed to be used with the +json+ exception, which will
contain information derived from the given exception.
three keys, "class", "message", and "backtrace", which
a single key, "exception", with a value being a hash with
:json :: Return a hash of exception information. The hash will have
false, doesn't use any JS.
:js_file :: A path to the external javascript file for the HTML exception page. If
doesn't use any CSS.
:css_file :: A path to the external CSS file for the HTML exception page. If false,
the backtrace (default: 7).
:context :: The number of context lines before and after each line in
use any CSS or JS.
is called in a nested block inside the route block. If false, doesn't
uses the string as a prefix, assuming that +r.exception_page_assets+
in the route block to serve the exception page assets. If a String,
+/exception_page.js+, assuming that +r.exception_page_assets+ is called
:assets :: If +true+, sets :css_file to +/exception_page.css+ and :js_file to
Options:
class, message, and backtrace.
is not accepted, then just show a plain text page with the exception
well as the GET, POST, cookie, and rack environment data. If text/html
with the ability to see the context for each backtrace line, as
and text/html is accepted, return an HTML page with the backtrace
string used for the body. If the Accept request header is present
Sets the Content-Type header in the response, and returns the
an exception handler, passing in the received exception.
more information for debugging. Designed to be called inside
Return a HTML page showing the exception, allowing a developer
def exception_page(exception, opts=OPTS) if opts[:json] @_response['Content-Type'] = "application/json" { "exception"=>{ "class"=>exception.class.to_s, "message"=>exception.message.to_s, "backtrace"=>exception.backtrace.map(&:to_s) } } elsif env['HTTP_ACCEPT'] =~ /text\/html/ @_response['Content-Type'] = "text/html" context = opts[:context] || 7 css_file = opts[:css_file] js_file = opts[:js_file] case prefix = opts[:assets] when false css_file = false if css_file.nil? js_file = false if js_file.nil? when nil # nothing else prefix = '' if prefix == true css_file ||= "#{prefix}/exception_page.css" js_file ||= "#{prefix}/exception_page.js" end css = case css_file when nil "<style type=\"text/css\">#{ExceptionPage.css}</style>" when false # :nothing else "<link rel=\"stylesheet\" href=\"#{h css_file}\" />" end js = case js_file when nil "<script type=\"text/javascript\">\n//<!--\n#{ExceptionPage.js}\n//-->\n</script>" when false # :nothing else "<script type=\"text/javascript\" src=\"#{h js_file}\"></script>" end frames = exception.backtrace.map.with_index do |line, i| frame = {:id=>i} if line =~ /\A(.*?):(\d+)(?::in `(.*)')?\Z/ filename = frame[:filename] = $1 lineno = frame[:lineno] = $2.to_i frame[:function] = $3 begin lineno -= 1 lines = ::File.readlines(filename) if line = lines[lineno] pre_lineno = [lineno-context, 0].max if (pre_context = lines[pre_lineno...lineno]) && !pre_context.empty? frame[:pre_context_lineno] = pre_lineno frame[:pre_context] = pre_context end post_lineno = [lineno+context, lines.size].min if (post_context = lines[lineno+1..post_lineno]) && !post_context.empty? frame[:post_context_lineno] = post_lineno frame[:post_context] = post_context end frame[:context_line] = line.chomp end rescue end frame end end.compact r = @_request begin post_data = r.POST missing_post = "No POST data" rescue missing_post = "Invalid POST data" end info = lambda do |title, id, var, none| <<END ="#{id}">#{title}</h3> && !var.empty?) ? (<<END1) : "<p>#{none}</p>" le class="req"> head> <tr> <th>Variable</th> <th>Value</th> </tr> thead> body> #{var.sort_by{|k, _| k.to_s}.map{|key, val| (<<END2)}.join <tr> <td>#{h key}</td> <td class="code"><div>#{h val.inspect}</div></td> </tr> tbody> ble> end <<END E html> ng="en"> http-equiv="content-type" content="text/html; charset=utf-8" /> >#{h exception.class} at #{h r.path}</title> "summary"> h exception.class} at #{h r.path}</h1> h exception.message}</h2> ><tr> Ruby</th> = frames.first) ? "<code>#{h first[:filename]}</code>: in <code>#{h first[:function]}</code>, line #{first[:lineno]}" : "unknown location"} > tr> Web</th> <code>#{r.request_method} #{h r.host}#{h r.path}</code></td> /table> mp to:</h3> ="quicklinks"> <a href="#get-info">GET</a></li> <a href="#post-info">POST</a></li> <a href="#cookie-info">Cookies</a></li> <a href="#env-info">ENV</a></li> "traceback"> aceback <span>(innermost first)</span></h2> ass="traceback"> .map{|frame| id = frame[:id]; (<<END1)}.join i class="frame"> <code>#{h frame[:filename]}:#{frame[:lineno]}</code> in <code>#{h frame[:function]}</code> #{frame[:context_line] ? (<<END2) : '</li>' <div class="context" id="c#{id}"> #{frame[:pre_context] ? (<<END3) : '' <ol start="#{frame[:pre_context_lineno]+1}" id="bc#{id}"> #{frame[:pre_context].map{|line| "<li>#{h line}</li>"}.join} </ol> <ol start="#{frame[:lineno]}" class="context-line"> <li>#{h frame[:context_line]}<span>...</span></li> </ol> #{frame[:post_context] ? (<<END4) : '' <ol start='#{frame[:lineno]+1}' id="ac#{id}"> #{frame[:post_context].map{|line| "<li>#{h line}</li>"}.join} </ol> </div> "requestinfo"> quest information</h2> .call('GET', 'get-info', r.GET, 'No GET data')} .call('POST', 'post-info', post_data, missing_post)} .call('Cookies', 'cookie-info', r.cookies, 'No cookie data')} .call('Rack ENV', 'env-info', r.env, 'No Rack env?')} "explanation"> re seeing this error because you use the Roda exception_page plugin. else @_response['Content-Type'] = "text/plain" "#{exception.class}: #{exception.message}\n#{exception.backtrace.map{|l| "\t#{l}"}.join("\n")}" end end