better_errors 2.5.0 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +56 -13
- data/Gemfile +1 -0
- data/README.md +32 -0
- data/better_errors.gemspec +12 -1
- data/gemfiles/rails42.gemfile +1 -0
- data/gemfiles/rails42_boc.gemfile +1 -0
- data/gemfiles/rails42_haml.gemfile +1 -0
- data/gemfiles/rails50.gemfile +1 -0
- data/gemfiles/rails50_boc.gemfile +1 -0
- data/gemfiles/rails50_haml.gemfile +1 -0
- data/gemfiles/rails51.gemfile +1 -0
- data/gemfiles/rails51_boc.gemfile +1 -0
- data/gemfiles/rails51_haml.gemfile +1 -0
- data/gemfiles/rails52.gemfile +1 -0
- data/gemfiles/rails52_boc.gemfile +1 -0
- data/gemfiles/rails52_haml.gemfile +1 -0
- data/gemfiles/rails60.gemfile +7 -0
- data/gemfiles/rails60_boc.gemfile +8 -0
- data/gemfiles/rails60_haml.gemfile +8 -0
- data/lib/better_errors.rb +6 -0
- data/lib/better_errors/error_page.rb +29 -6
- data/lib/better_errors/middleware.rb +59 -12
- data/lib/better_errors/raised_exception.rb +13 -5
- data/lib/better_errors/stack_frame.rb +8 -2
- data/lib/better_errors/templates/main.erb +24 -2
- data/lib/better_errors/templates/variable_info.erb +8 -1
- data/lib/better_errors/version.rb +1 -1
- metadata +27 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10f7411145be495cf17cbebdf087e1bb21fe8c6fc8c07397fa406e7fc1f9f917
|
4
|
+
data.tar.gz: 3b14b75eaa97285c3ad5f685671348694aa7174cc43e52826e49e21a2f139b0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 141e1056c402ed7b0aa0965278018096ca1d2bc4032072692c1f146ad09d6848d87792d665ecc6dcb41322594e91d9a5e27955edc560bb665a2995f150c0be4e
|
7
|
+
data.tar.gz: 03a94aa9fdcd0340b1fdf913a52978437692587efabe196ebb119087712086cc304289ec1c684ab4efbdece115a4bd1298b57bf58699a0d672f76f6aa196793b
|
data/.travis.yml
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
sudo: false
|
2
1
|
language: ruby
|
3
2
|
cache: bundler
|
4
|
-
before_install:
|
5
|
-
- gem update --system
|
6
|
-
- gem update bundler
|
7
3
|
notifications:
|
8
4
|
webhooks:
|
9
5
|
# With COVERALLS_PARALLEL, coverage information sent to coveralls will not be processed until
|
@@ -12,23 +8,28 @@ notifications:
|
|
12
8
|
- secure: "YnHYbTq51ySistjvOxsuNhyg4GLuUffEJstTYeGYXiBF7HG5h43IVYo8KNuLzwkgsOYBcNo+YMdQX7qCqJffSbhsr1FZRSzBmjFFxcyD4hu+ukM2theZ4mePVAZiePscYvQPRNY4hIb4d3egStJEytkalDhB3sOebF57tIaCssg="
|
13
9
|
rvm:
|
14
10
|
- 2.2.10
|
15
|
-
- 2.3.
|
16
|
-
- 2.4.
|
17
|
-
- 2.5.
|
11
|
+
- 2.3.8
|
12
|
+
- 2.4.9
|
13
|
+
- 2.5.7
|
14
|
+
- 2.6.5
|
15
|
+
- 2.7.0
|
18
16
|
- ruby-head
|
19
17
|
gemfile:
|
20
18
|
- gemfiles/rails42.gemfile
|
21
19
|
- gemfiles/rails50.gemfile
|
22
20
|
- gemfiles/rails51.gemfile
|
23
21
|
- gemfiles/rails52.gemfile
|
22
|
+
- gemfiles/rails60.gemfile
|
24
23
|
- gemfiles/rails42_haml.gemfile
|
25
24
|
- gemfiles/rails50_haml.gemfile
|
26
25
|
- gemfiles/rails51_haml.gemfile
|
27
26
|
- gemfiles/rails52_haml.gemfile
|
27
|
+
- gemfiles/rails60_haml.gemfile
|
28
28
|
- gemfiles/rails42_boc.gemfile
|
29
29
|
- gemfiles/rails50_boc.gemfile
|
30
30
|
- gemfiles/rails51_boc.gemfile
|
31
31
|
- gemfiles/rails52_boc.gemfile
|
32
|
+
- gemfiles/rails60_boc.gemfile
|
32
33
|
- gemfiles/rack.gemfile
|
33
34
|
- gemfiles/rack_boc.gemfile
|
34
35
|
- gemfiles/pry09.gemfile
|
@@ -41,15 +42,57 @@ matrix:
|
|
41
42
|
- gemfile: gemfiles/pry010.gemfile
|
42
43
|
- gemfile: gemfiles/pry011.gemfile
|
43
44
|
exclude:
|
44
|
-
- rvm: 2.
|
45
|
+
- rvm: 2.2.10
|
46
|
+
gemfile: gemfiles/rails60.gemfile
|
47
|
+
- rvm: 2.2.10
|
48
|
+
gemfile: gemfiles/rails60_boc.gemfile
|
49
|
+
- rvm: 2.2.10
|
50
|
+
gemfile: gemfiles/rails60_haml.gemfile
|
51
|
+
- rvm: 2.3.8
|
45
52
|
gemfile: gemfiles/rails42.gemfile
|
46
|
-
- rvm: 2.
|
53
|
+
- rvm: 2.3.8
|
47
54
|
gemfile: gemfiles/rails42_boc.gemfile
|
48
|
-
- rvm: 2.
|
55
|
+
- rvm: 2.3.8
|
49
56
|
gemfile: gemfiles/rails42_haml.gemfile
|
50
|
-
- rvm: 2.
|
57
|
+
- rvm: 2.3.8
|
58
|
+
gemfile: gemfiles/rails60.gemfile
|
59
|
+
- rvm: 2.3.8
|
60
|
+
gemfile: gemfiles/rails60_boc.gemfile
|
61
|
+
- rvm: 2.3.8
|
62
|
+
gemfile: gemfiles/rails60_haml.gemfile
|
63
|
+
- rvm: 2.4.9
|
51
64
|
gemfile: gemfiles/rails42.gemfile
|
52
|
-
- rvm: 2.
|
65
|
+
- rvm: 2.4.9
|
53
66
|
gemfile: gemfiles/rails42_boc.gemfile
|
54
|
-
- rvm: 2.
|
67
|
+
- rvm: 2.4.9
|
68
|
+
gemfile: gemfiles/rails42_haml.gemfile
|
69
|
+
- rvm: 2.4.9
|
70
|
+
gemfile: gemfiles/rails60.gemfile
|
71
|
+
- rvm: 2.4.9
|
72
|
+
gemfile: gemfiles/rails60_boc.gemfile
|
73
|
+
- rvm: 2.4.9
|
74
|
+
gemfile: gemfiles/rails60_haml.gemfile
|
75
|
+
- rvm: 2.5.7
|
76
|
+
gemfile: gemfiles/rails42.gemfile
|
77
|
+
- rvm: 2.5.7
|
78
|
+
gemfile: gemfiles/rails42_boc.gemfile
|
79
|
+
- rvm: 2.5.7
|
80
|
+
gemfile: gemfiles/rails42_haml.gemfile
|
81
|
+
- rvm: 2.6.5
|
82
|
+
gemfile: gemfiles/rails42.gemfile
|
83
|
+
- rvm: 2.6.5
|
84
|
+
gemfile: gemfiles/rails42_boc.gemfile
|
85
|
+
- rvm: 2.6.5
|
86
|
+
gemfile: gemfiles/rails42_haml.gemfile
|
87
|
+
- rvm: 2.7.0
|
88
|
+
gemfile: gemfiles/rails42.gemfile
|
89
|
+
- rvm: 2.7.0
|
90
|
+
gemfile: gemfiles/rails42_boc.gemfile
|
91
|
+
- rvm: 2.7.0
|
92
|
+
gemfile: gemfiles/rails42_haml.gemfile
|
93
|
+
- rvm: ruby-head
|
94
|
+
gemfile: gemfiles/rails42.gemfile
|
95
|
+
- rvm: ruby-head
|
96
|
+
gemfile: gemfiles/rails42_boc.gemfile
|
97
|
+
- rvm: ruby-head
|
55
98
|
gemfile: gemfiles/rails42_haml.gemfile
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -35,6 +35,28 @@ end
|
|
35
35
|
|
36
36
|
_Note: If you discover that Better Errors isn't working - particularly after upgrading from version 0.5.0 or less - be sure to set `config.consider_all_requests_local = true` in `config/environments/development.rb`._
|
37
37
|
|
38
|
+
### Optional: Set `EDITOR`
|
39
|
+
|
40
|
+
For many reasons outside of Better Errors, you should have the `EDITOR` environment variable set to your preferred
|
41
|
+
editor.
|
42
|
+
Better Errors, like many other tools, will use that environment variable to show a link that opens your
|
43
|
+
editor to the file and line from the console.
|
44
|
+
|
45
|
+
By default the links will open TextMate-protocol links.
|
46
|
+
|
47
|
+
To see if your editor is supported or to set up a different editor, see [the wiki](https://github.com/BetterErrors/better_errors/wiki/Link-to-your-editor).
|
48
|
+
|
49
|
+
### Optional: Set `BETTER_ERRORS_INSIDE_FRAME`
|
50
|
+
|
51
|
+
If your application is running inside of an iframe, or if you have a Content Security Policy that disallows links
|
52
|
+
to other protocols, the editor links will not work.
|
53
|
+
|
54
|
+
To work around this set `BETTER_ERRORS_INSIDE_FRAME=1` in the environment, and the links will include `target=_blank`,
|
55
|
+
allowing the link to open regardless of the policy.
|
56
|
+
|
57
|
+
_This works because it opens the editor from a new browser tab, escaping from the restrictions of your site._
|
58
|
+
_Unfortunately it leaves behind an empty tab each time, so only use this if needed._
|
59
|
+
|
38
60
|
## Security
|
39
61
|
|
40
62
|
**NOTE:** It is *critical* you put better\_errors only in the **development** section of your Gemfile.
|
@@ -93,6 +115,16 @@ See [the wiki for instructions on configuring the editor](https://github.com/Bet
|
|
93
115
|
BetterErrors.maximum_variable_inspect_size = 100_000
|
94
116
|
```
|
95
117
|
|
118
|
+
## Ignore inspection of variables with certain classes.
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
# e.g. in config/initializers/better_errors.rb
|
122
|
+
# This will stop BetterErrors from trying to inspect objects of these classes, which can cause
|
123
|
+
# slow loading times and unneccessary database queries. Does not check inheritance chain, use
|
124
|
+
# strings not contants.
|
125
|
+
# default value: ['ActionDispatch::Request', 'ActionDispatch::Response']
|
126
|
+
BetterErrors.ignored_classes = ['ActionDispatch::Request', 'ActionDispatch::Response']
|
127
|
+
```
|
96
128
|
|
97
129
|
## Get in touch!
|
98
130
|
|
data/better_errors.gemspec
CHANGED
@@ -22,9 +22,12 @@ Gem::Specification.new do |s|
|
|
22
22
|
|
23
23
|
s.add_development_dependency "rake", "~> 10.0"
|
24
24
|
s.add_development_dependency "rspec", "~> 3.5"
|
25
|
+
s.add_development_dependency "rspec-html-matchers"
|
25
26
|
s.add_development_dependency "rspec-its"
|
26
27
|
s.add_development_dependency "yard"
|
27
|
-
|
28
|
+
# kramdown 2.1 requires Ruby 2.3+
|
29
|
+
s.add_development_dependency "kramdown", (RUBY_VERSION < '2.3' ? '< 2.0.0' : '> 2.0.0')
|
30
|
+
# simplecov and coveralls must not be included here. See the Gemfiles instead.
|
28
31
|
|
29
32
|
s.add_dependency "erubi", ">= 1.0.0"
|
30
33
|
s.add_dependency "coderay", ">= 1.0.0"
|
@@ -33,4 +36,12 @@ Gem::Specification.new do |s|
|
|
33
36
|
# optional dependencies:
|
34
37
|
# s.add_dependency "binding_of_caller"
|
35
38
|
# s.add_dependency "pry"
|
39
|
+
|
40
|
+
if s.respond_to?(:metadata)
|
41
|
+
s.metadata['changelog_uri'] = 'https://github.com/BetterErrors/better_errors/releases'
|
42
|
+
s.metadata['source_code_uri'] = 'https://github.com/BetterErrors/better_errors'
|
43
|
+
s.metadata['bug_tracker_uri'] = 'https://github.com/BetterErrors/better_errors/issues'
|
44
|
+
else
|
45
|
+
puts "Your RubyGems does not support metadata. Update if you'd like to make a release."
|
46
|
+
end
|
36
47
|
end
|
data/gemfiles/rails42.gemfile
CHANGED
data/gemfiles/rails50.gemfile
CHANGED
data/gemfiles/rails51.gemfile
CHANGED
data/gemfiles/rails52.gemfile
CHANGED
data/lib/better_errors.rb
CHANGED
@@ -21,6 +21,7 @@ module BetterErrors
|
|
21
21
|
{ symbols: [:idea], sniff: /idea/i, url: "idea://open?file=%{file}&line=%{line}" },
|
22
22
|
{ symbols: [:rubymine], sniff: /mine/i, url: "x-mine://open?file=%{file}&line=%{line}" },
|
23
23
|
{ symbols: [:vscode, :code], sniff: /code/i, url: "vscode://file/%{file}:%{line}" },
|
24
|
+
{ symbols: [:vscodium, :codium], sniff: /codium/i, url: "vscodium://file/%{file}:%{line}" },
|
24
25
|
{ symbols: [:atom], sniff: /atom/i, url: "atom://core/open/file?filename=%{file}&line=%{line}" },
|
25
26
|
]
|
26
27
|
|
@@ -54,9 +55,14 @@ module BetterErrors
|
|
54
55
|
# the variable won't be returned.
|
55
56
|
# @return int
|
56
57
|
attr_accessor :maximum_variable_inspect_size
|
58
|
+
|
59
|
+
# List of classes that are excluded from inspection.
|
60
|
+
# @return [Array]
|
61
|
+
attr_accessor :ignored_classes
|
57
62
|
end
|
58
63
|
@ignored_instance_variables = []
|
59
64
|
@maximum_variable_inspect_size = 100_000
|
65
|
+
@ignored_classes = ['ActionDispatch::Request', 'ActionDispatch::Response']
|
60
66
|
|
61
67
|
# Returns a proc, which when called with a filename and line number argument,
|
62
68
|
# returns a URL to open the filename and line in the selected editor.
|
@@ -26,8 +26,13 @@ module BetterErrors
|
|
26
26
|
@id ||= SecureRandom.hex(8)
|
27
27
|
end
|
28
28
|
|
29
|
-
def render(template_name = "main")
|
29
|
+
def render(template_name = "main", csrf_token = nil)
|
30
30
|
binding.eval(self.class.template(template_name).src)
|
31
|
+
rescue => e
|
32
|
+
# Fix the backtrace, which doesn't identify the template that failed (within Better Errors).
|
33
|
+
# We don't know the line number, so just injecting the template path has to be enough.
|
34
|
+
e.backtrace.unshift "#{self.class.template_path(template_name)}:0"
|
35
|
+
raise
|
31
36
|
end
|
32
37
|
|
33
38
|
def do_variables(opts)
|
@@ -59,7 +64,19 @@ module BetterErrors
|
|
59
64
|
end
|
60
65
|
|
61
66
|
def exception_message
|
62
|
-
exception.message.
|
67
|
+
exception.message.strip.gsub(/(\r?\n\s*\r?\n)+/, "\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
def active_support_actions
|
71
|
+
return [] unless defined?(ActiveSupport::ActionableError)
|
72
|
+
|
73
|
+
ActiveSupport::ActionableError.actions(exception.type)
|
74
|
+
end
|
75
|
+
|
76
|
+
def action_dispatch_action_endpoint
|
77
|
+
return unless defined?(ActionDispatch::ActionableExceptions)
|
78
|
+
|
79
|
+
ActionDispatch::ActionableExceptions.endpoint
|
63
80
|
end
|
64
81
|
|
65
82
|
def application_frames
|
@@ -105,11 +122,17 @@ module BetterErrors
|
|
105
122
|
end
|
106
123
|
|
107
124
|
def inspect_value(obj)
|
108
|
-
|
125
|
+
if BetterErrors.ignored_classes.include? obj.class.name
|
126
|
+
"<span class='unsupported'>(Instance of ignored class. "\
|
127
|
+
"#{obj.class.name ? "Remove #{CGI.escapeHTML(obj.class.name)} from" : "Modify"}"\
|
128
|
+
" BetterErrors.ignored_classes if you need to see it.)</span>"
|
129
|
+
else
|
130
|
+
InspectableValue.new(obj).to_html
|
131
|
+
end
|
109
132
|
rescue BetterErrors::ValueLargerThanConfiguredMaximum
|
110
|
-
"<span class='unsupported'>(
|
111
|
-
"Modify #{CGI.escapeHTML(obj.class.name)}#inspect "\
|
112
|
-
"
|
133
|
+
"<span class='unsupported'>(Object too large. "\
|
134
|
+
"#{obj.class.name ? "Modify #{CGI.escapeHTML(obj.class.name)}#inspect or a" : "A"}"\
|
135
|
+
"djust BetterErrors.maximum_variable_inspect_size if you need to see it.)</span>"
|
113
136
|
rescue Exception => e
|
114
137
|
"<span class='unsupported'>(exception #{CGI.escapeHTML(e.class.to_s)} was raised in inspect)</span>"
|
115
138
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "json"
|
2
2
|
require "ipaddr"
|
3
|
+
require "securerandom"
|
3
4
|
require "set"
|
4
5
|
require "rack"
|
5
6
|
|
@@ -33,12 +34,14 @@ module BetterErrors
|
|
33
34
|
# Adds an address to the set of IP addresses allowed to access Better
|
34
35
|
# Errors.
|
35
36
|
def self.allow_ip!(addr)
|
36
|
-
ALLOWED_IPS << IPAddr.new(addr)
|
37
|
+
ALLOWED_IPS << (addr.is_a?(IPAddr) ? addr : IPAddr.new(addr))
|
37
38
|
end
|
38
39
|
|
39
40
|
allow_ip! "127.0.0.0/8"
|
40
41
|
allow_ip! "::1/128" rescue nil # windows ruby doesn't have ipv6 support
|
41
42
|
|
43
|
+
CSRF_TOKEN_COOKIE_NAME = 'BetterErrors-CSRF-Token'
|
44
|
+
|
42
45
|
# A new instance of BetterErrors::Middleware
|
43
46
|
#
|
44
47
|
# @param app The Rack app/middleware to wrap with Better Errors
|
@@ -72,7 +75,7 @@ module BetterErrors
|
|
72
75
|
def better_errors_call(env)
|
73
76
|
case env["PATH_INFO"]
|
74
77
|
when %r{/__better_errors/(?<id>.+?)/(?<method>\w+)\z}
|
75
|
-
internal_call
|
78
|
+
internal_call(env, $~[:id], $~[:method])
|
76
79
|
when %r{/__better_errors/?\z}
|
77
80
|
show_error_page env
|
78
81
|
else
|
@@ -89,11 +92,14 @@ module BetterErrors
|
|
89
92
|
end
|
90
93
|
|
91
94
|
def show_error_page(env, exception=nil)
|
95
|
+
request = Rack::Request.new(env)
|
96
|
+
csrf_token = request.cookies[CSRF_TOKEN_COOKIE_NAME] || SecureRandom.uuid
|
97
|
+
|
92
98
|
type, content = if @error_page
|
93
99
|
if text?(env)
|
94
100
|
[ 'plain', @error_page.render('text') ]
|
95
101
|
else
|
96
|
-
[ 'html', @error_page.render ]
|
102
|
+
[ 'html', @error_page.render('main', csrf_token) ]
|
97
103
|
end
|
98
104
|
else
|
99
105
|
[ 'html', no_errors_page ]
|
@@ -104,12 +110,22 @@ module BetterErrors
|
|
104
110
|
status_code = ActionDispatch::ExceptionWrapper.new(env, exception).status_code
|
105
111
|
end
|
106
112
|
|
107
|
-
|
113
|
+
response = Rack::Response.new(content, status_code, { "Content-Type" => "text/#{type}; charset=utf-8" })
|
114
|
+
|
115
|
+
unless request.cookies[CSRF_TOKEN_COOKIE_NAME]
|
116
|
+
response.set_cookie(CSRF_TOKEN_COOKIE_NAME, value: csrf_token, httponly: true, same_site: :strict)
|
117
|
+
end
|
118
|
+
|
119
|
+
# In older versions of Rack, the body returned here is actually a Rack::BodyProxy which seems to be a bug.
|
120
|
+
# (It contains status, headers and body and does not act like an array of strings.)
|
121
|
+
# Since we already have status code and body here, there's no need to use the ones in the Rack::Response.
|
122
|
+
(_status_code, headers, _body) = response.finish
|
123
|
+
[status_code, headers, [content]]
|
108
124
|
end
|
109
125
|
|
110
126
|
def text?(env)
|
111
127
|
env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest" ||
|
112
|
-
|
128
|
+
!env["HTTP_ACCEPT"].to_s.include?('html')
|
113
129
|
end
|
114
130
|
|
115
131
|
def log_exception
|
@@ -129,13 +145,22 @@ module BetterErrors
|
|
129
145
|
end
|
130
146
|
end
|
131
147
|
|
132
|
-
def internal_call(env,
|
148
|
+
def internal_call(env, id, method)
|
149
|
+
return not_found_json_response unless %w[variables eval].include?(method)
|
133
150
|
return no_errors_json_response unless @error_page
|
134
|
-
return invalid_error_json_response if
|
151
|
+
return invalid_error_json_response if id != @error_page.id
|
152
|
+
|
153
|
+
request = Rack::Request.new(env)
|
154
|
+
return invalid_csrf_token_json_response unless request.cookies[CSRF_TOKEN_COOKIE_NAME]
|
155
|
+
|
156
|
+
request.body.rewind
|
157
|
+
body = JSON.parse(request.body.read)
|
158
|
+
return invalid_csrf_token_json_response unless request.cookies[CSRF_TOKEN_COOKIE_NAME] == body['csrfToken']
|
159
|
+
|
160
|
+
return not_acceptable_json_response unless request.content_type == 'application/json'
|
135
161
|
|
136
|
-
|
137
|
-
|
138
|
-
[200, { "Content-Type" => "text/plain; charset=utf-8" }, [JSON.dump(response)]]
|
162
|
+
response = @error_page.send("do_#{method}", body)
|
163
|
+
[200, { "Content-Type" => "application/json; charset=utf-8" }, [JSON.dump(response)]]
|
139
164
|
end
|
140
165
|
|
141
166
|
def no_errors_page
|
@@ -157,18 +182,40 @@ module BetterErrors
|
|
157
182
|
"The application has been restarted since this page loaded, " +
|
158
183
|
"or the framework is reloading all gems before each request "
|
159
184
|
end
|
160
|
-
[200, { "Content-Type" => "
|
185
|
+
[200, { "Content-Type" => "application/json; charset=utf-8" }, [JSON.dump(
|
161
186
|
error: 'No exception information available',
|
162
187
|
explanation: explanation,
|
163
188
|
)]]
|
164
189
|
end
|
165
190
|
|
166
191
|
def invalid_error_json_response
|
167
|
-
[200, { "Content-Type" => "
|
192
|
+
[200, { "Content-Type" => "application/json; charset=utf-8" }, [JSON.dump(
|
168
193
|
error: "Session expired",
|
169
194
|
explanation: "This page was likely opened from a previous exception, " +
|
170
195
|
"and the exception is no longer available in memory.",
|
171
196
|
)]]
|
172
197
|
end
|
198
|
+
|
199
|
+
def invalid_csrf_token_json_response
|
200
|
+
[200, { "Content-Type" => "application/json; charset=utf-8" }, [JSON.dump(
|
201
|
+
error: "Invalid CSRF Token",
|
202
|
+
explanation: "The browser session might have been cleared, " +
|
203
|
+
"or something went wrong.",
|
204
|
+
)]]
|
205
|
+
end
|
206
|
+
|
207
|
+
def not_found_json_response
|
208
|
+
[404, { "Content-Type" => "application/json; charset=utf-8" }, [JSON.dump(
|
209
|
+
error: "Not found",
|
210
|
+
explanation: "Not a recognized internal call.",
|
211
|
+
)]]
|
212
|
+
end
|
213
|
+
|
214
|
+
def not_acceptable_json_response
|
215
|
+
[406, { "Content-Type" => "application/json; charset=utf-8" }, [JSON.dump(
|
216
|
+
error: "Request not acceptable",
|
217
|
+
explanation: "The internal request did not match an acceptable content type.",
|
218
|
+
)]]
|
219
|
+
end
|
173
220
|
end
|
174
221
|
end
|
@@ -4,9 +4,8 @@ module BetterErrors
|
|
4
4
|
attr_reader :exception, :message, :backtrace
|
5
5
|
|
6
6
|
def initialize(exception)
|
7
|
-
if exception.respond_to?(:
|
8
|
-
|
9
|
-
elsif exception.respond_to?(:original_exception) && exception.original_exception
|
7
|
+
if exception.respond_to?(:original_exception) && exception.original_exception
|
8
|
+
# This supports some specific Rails exceptions, and is not intended to act the same as `#cause`.
|
10
9
|
exception = exception.original_exception
|
11
10
|
end
|
12
11
|
|
@@ -36,8 +35,13 @@ module BetterErrors
|
|
36
35
|
|
37
36
|
def setup_backtrace_from_bindings
|
38
37
|
@backtrace = exception.__better_errors_bindings_stack.map { |binding|
|
39
|
-
|
40
|
-
|
38
|
+
if binding.respond_to?(:source_location) # Ruby >= 2.6
|
39
|
+
file = binding.source_location[0]
|
40
|
+
line = binding.source_location[1]
|
41
|
+
else
|
42
|
+
file = binding.eval "__FILE__"
|
43
|
+
line = binding.eval "__LINE__"
|
44
|
+
end
|
41
45
|
name = binding.frame_description
|
42
46
|
StackFrame.new(file, line, name, binding)
|
43
47
|
}
|
@@ -53,6 +57,10 @@ module BetterErrors
|
|
53
57
|
|
54
58
|
def massage_syntax_error
|
55
59
|
case exception.class.to_s
|
60
|
+
when "ActionView::Template::Error"
|
61
|
+
if exception.respond_to?(:file_name) && exception.respond_to?(:line_number)
|
62
|
+
backtrace.unshift(StackFrame.new(exception.file_name, exception.line_number.to_i, "view template"))
|
63
|
+
end
|
56
64
|
when "Haml::SyntaxError", "Sprockets::Coffeelint::Error"
|
57
65
|
if /\A(.+?):(\d+)/ =~ exception.backtrace.first
|
58
66
|
backtrace.unshift(StackFrame.new($1, $2.to_i, ""))
|
@@ -69,7 +69,10 @@ module BetterErrors
|
|
69
69
|
def local_variables
|
70
70
|
return {} unless frame_binding
|
71
71
|
|
72
|
-
frame_binding.eval("local_variables")
|
72
|
+
lv = frame_binding.eval("local_variables")
|
73
|
+
return {} unless lv
|
74
|
+
|
75
|
+
lv.each_with_object({}) do |name, hash|
|
73
76
|
# Ruby 2.2's local_variables will include the hidden #$! variable if
|
74
77
|
# called from within a rescue context. This is not a valid variable name,
|
75
78
|
# so the local_variable_get method complains. This should probably be
|
@@ -94,7 +97,10 @@ module BetterErrors
|
|
94
97
|
end
|
95
98
|
|
96
99
|
def visible_instance_variables
|
97
|
-
frame_binding.eval("instance_variables")
|
100
|
+
iv = frame_binding.eval("instance_variables")
|
101
|
+
return {} unless iv
|
102
|
+
|
103
|
+
iv - BetterErrors.ignored_instance_variables
|
98
104
|
end
|
99
105
|
|
100
106
|
def to_s
|
@@ -146,6 +146,14 @@
|
|
146
146
|
}
|
147
147
|
|
148
148
|
/* Heading */
|
149
|
+
header.exception .fix-actions {
|
150
|
+
margin-top: .5em;
|
151
|
+
}
|
152
|
+
|
153
|
+
header.exception .fix-actions input[type=submit] {
|
154
|
+
font-weight: bold;
|
155
|
+
}
|
156
|
+
|
149
157
|
header.exception h2 {
|
150
158
|
font-weight: 200;
|
151
159
|
font-size: 11pt;
|
@@ -153,7 +161,7 @@
|
|
153
161
|
|
154
162
|
header.exception h2,
|
155
163
|
header.exception p {
|
156
|
-
line-height: 1.
|
164
|
+
line-height: 1.5em;
|
157
165
|
overflow: hidden;
|
158
166
|
white-space: pre;
|
159
167
|
text-overflow: ellipsis;
|
@@ -166,7 +174,7 @@
|
|
166
174
|
|
167
175
|
header.exception p {
|
168
176
|
font-weight: 200;
|
169
|
-
font-size:
|
177
|
+
font-size: 17pt;
|
170
178
|
color: white;
|
171
179
|
}
|
172
180
|
|
@@ -744,6 +752,18 @@
|
|
744
752
|
<header class="exception">
|
745
753
|
<h2><strong><%= exception_type %></strong> <span>at <%= request_path %></span></h2>
|
746
754
|
<p><%= exception_message %></p>
|
755
|
+
<% unless active_support_actions.empty? %>
|
756
|
+
<div class='fix-actions'>
|
757
|
+
<% active_support_actions.each do |action, _| %>
|
758
|
+
<form class="button_to" method="post" action="<%= action_dispatch_action_endpoint %>">
|
759
|
+
<input type="submit" value="<%= action %>">
|
760
|
+
<input type="hidden" name="action" value="<%= action %>">
|
761
|
+
<input type="hidden" name="error" value="<%= exception_type %>">
|
762
|
+
<input type="hidden" name="location" value="<%= request_path %>">
|
763
|
+
</form>
|
764
|
+
<% end %>
|
765
|
+
</div>
|
766
|
+
<% end %>
|
747
767
|
</header>
|
748
768
|
</div>
|
749
769
|
|
@@ -780,6 +800,7 @@
|
|
780
800
|
(function() {
|
781
801
|
|
782
802
|
var OID = "<%= id %>";
|
803
|
+
var csrfToken = "<%= csrf_token %>";
|
783
804
|
|
784
805
|
var previousFrame = null;
|
785
806
|
var previousFrameInfo = null;
|
@@ -790,6 +811,7 @@
|
|
790
811
|
var req = new XMLHttpRequest();
|
791
812
|
req.open("POST", "//" + window.location.host + <%== uri_prefix.gsub("<", "<").inspect %> + "/__better_errors/" + OID + "/" + method, true);
|
792
813
|
req.setRequestHeader("Content-Type", "application/json");
|
814
|
+
opts.csrfToken = csrfToken;
|
793
815
|
req.send(JSON.stringify(opts));
|
794
816
|
req.onreadystatechange = function() {
|
795
817
|
if(req.readyState == 4) {
|
@@ -1,7 +1,14 @@
|
|
1
1
|
<header class="trace_info clearfix">
|
2
2
|
<div class="title">
|
3
3
|
<h2 class="name"><%= @frame.name %></h2>
|
4
|
-
<div class="location"
|
4
|
+
<div class="location">
|
5
|
+
<span class="filename">
|
6
|
+
<a
|
7
|
+
href="<%= editor_url(@frame) %>"
|
8
|
+
<%= ENV.key?('BETTER_ERRORS_INSIDE_FRAME') ? "target=_blank" : '' %>
|
9
|
+
><%= @frame.pretty_path %></a>
|
10
|
+
</span>
|
11
|
+
</div>
|
5
12
|
</div>
|
6
13
|
<div class="code_block clearfix">
|
7
14
|
<%== html_formatted_code_block @frame %>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: better_errors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charlie Somerville
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.5'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec-
|
42
|
+
name: rspec-html-matchers
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec-its
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: yard
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: kramdown
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 2.0.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 2.0.0
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: erubi
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,6 +171,9 @@ files:
|
|
157
171
|
- gemfiles/rails52.gemfile
|
158
172
|
- gemfiles/rails52_boc.gemfile
|
159
173
|
- gemfiles/rails52_haml.gemfile
|
174
|
+
- gemfiles/rails60.gemfile
|
175
|
+
- gemfiles/rails60_boc.gemfile
|
176
|
+
- gemfiles/rails60_haml.gemfile
|
160
177
|
- lib/better_errors.rb
|
161
178
|
- lib/better_errors/code_formatter.rb
|
162
179
|
- lib/better_errors/code_formatter/html.rb
|
@@ -178,7 +195,10 @@ files:
|
|
178
195
|
homepage: https://github.com/BetterErrors/better_errors
|
179
196
|
licenses:
|
180
197
|
- MIT
|
181
|
-
metadata:
|
198
|
+
metadata:
|
199
|
+
changelog_uri: https://github.com/BetterErrors/better_errors/releases
|
200
|
+
source_code_uri: https://github.com/BetterErrors/better_errors
|
201
|
+
bug_tracker_uri: https://github.com/BetterErrors/better_errors/issues
|
182
202
|
post_install_message:
|
183
203
|
rdoc_options: []
|
184
204
|
require_paths:
|
@@ -194,8 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
214
|
- !ruby/object:Gem::Version
|
195
215
|
version: '0'
|
196
216
|
requirements: []
|
197
|
-
|
198
|
-
rubygems_version: 2.7.6
|
217
|
+
rubygems_version: 3.1.2
|
199
218
|
signing_key:
|
200
219
|
specification_version: 4
|
201
220
|
summary: Better error page for Rails and other Rack apps
|