Class: Rackr::Router::DevHtml::Errors

Inherits:
Object
  • Object
show all
Includes:
Action
Defined in:
lib/rackr/router/dev_html/errors.rb

Overview

This is the action that is called when an error is raised

Constant Summary

Constants included from Action

Action::BUILD_RESPONSE, Action::DEFAULT_CSP_HEADERS, Action::DEFAULT_HEADERS, Action::MIME_TYPES, Action::RENDER

Instance Method Summary collapse

Methods included from Action

included

Instance Method Details

#backtrace(env) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/rackr/router/dev_html/errors.rb', line 54

def backtrace(env)
  first, *tail = env['error'].backtrace
  traceback = +'<h2>Traceback <span>(innermost first)</span></h2>'
  traceback << "<p class=\"first-p\">#{first}</p><br/>"

  line_number = extract_line_number(first)
  match = first.match(%r{^(/[[\w/.-]]+)})
  file_path = (match ? match[1] : nil)
  unless file_path.nil?
    lines = File.readlines(file_path).map.with_index { |line, i| "#{i + 1}: #{line}" }
    traceback << "<pre>#{slice_around_index(lines, line_number).join}</pre>"
  end

  traceback << "<p>#{tail.join('<br>')}</p>"
  traceback
end

#call(env) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rackr/router/dev_html/errors.rb', line 10

def call(env)
  res = build_response(html: <<-HTML
    <!DOCTYPE html>
    <html>
    <head>
      <title>Application error</title>
      <style>
        html * { padding:0; margin:0; }
        body * { padding:10px 20px; }
        body * * { padding:0; }
        body { font:small sans-serif; }
        body>div { border-bottom:1px solid #ddd; }
        h1 { font-weight:normal; }
        h2 { margin-bottom:.8em; }
        h2 span { font-size:80%; color:#555; font-weight:normal; }
        #summary { background: #ffc; }
        #summary h2 { font-weight: normal; color: #555; }
        #backtrace { background: #eee; }
        pre {
          background: #ddd;
          padding: 1em;
          margin-bottom: 1em;
        }
        p {
          font-family: monospace;
        }
      </style>
    </head>
    <body>
      <div id="summary">
        <h1>#{env['error'].class}</h1>
        <h2>#{env['error'].message.size > 1000 ? "#{env['error'].message.slice(0, 1000)} ..." : env['error'].message}</h2>
      </div>
      <div id="backtrace">
        #{backtrace(env)}
      </div>
    </body>
    </html>
  HTML
                      )
  res.status = 500
  render res:
end

#extract_line_number(input) ⇒ Object



71
72
73
74
75
# File 'lib/rackr/router/dev_html/errors.rb', line 71

def extract_line_number(input)
  if (match = input.match(/:(\d+):in/))
    match[1].to_i
  end
end

#slice_around_index(array, index) ⇒ Object



77
78
79
80
81
82
83
84
85
# File 'lib/rackr/router/dev_html/errors.rb', line 77

def slice_around_index(array, index)
  return array if index.nil? || index < 1

  index -= 1
  start_index = [index - 2, 0].max
  end_index = [index + 2, array.size - 1].min

  array[start_index..end_index]
end