module Roda::RodaPlugins::ExceptionPage::InstanceMethods

def exception_page(exception, opts=OPTS)

automatically convert the hash to JSON format.
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