better_errors 2.5.1 → 2.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +69 -20
- data/README.md +32 -0
- data/better_errors.gemspec +3 -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 +26 -3
- data/lib/better_errors/middleware.rb +59 -12
- data/lib/better_errors/raised_exception.rb +17 -3
- 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 +23 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59e37a4996e35b2775a359cbe11302a8ded7213d7e940905a92cfe39d872e2e9
|
4
|
+
data.tar.gz: f162b4cbb8d5fc3c285c466ecbfb449626337e724cd0c8964fcbc7fb3784288b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36a80fb99501720b6dda49b61dac22deefa30b9bfcc46b7c00c7ec293dc0de4400dcdb4ac3b35d46d3d6722d8bf79a5e7ace2481c3c91ad1b0310900135aa802
|
7
|
+
data.tar.gz: 3d3c7f3eea41454551f3fa21dd8721da779eaa676f97520946fcb8294e20c3bdddb88fd613bfd43cdf0edaf434583c8c93ddc3ad099fddc8e8179598c70b9e92
|
data/.travis.yml
CHANGED
@@ -1,16 +1,5 @@
|
|
1
|
-
sudo: false
|
2
1
|
language: ruby
|
3
2
|
cache: bundler
|
4
|
-
before_install:
|
5
|
-
# Since Rails 4.2 only supports rubygems < 2, we must install an older version for it.
|
6
|
-
- >
|
7
|
-
if [[ "$BUNDLE_GEMFILE" =~ "rails42" ]]; then
|
8
|
-
rvm @global do gem install rubygems-update -v '<2'
|
9
|
-
update_rubygems
|
10
|
-
rvm @global do gem uninstall bundler --force --executables
|
11
|
-
rvm @global do gem install bundler -v "~> 1.3"
|
12
|
-
fi
|
13
|
-
|
14
3
|
notifications:
|
15
4
|
webhooks:
|
16
5
|
# With COVERALLS_PARALLEL, coverage information sent to coveralls will not be processed until
|
@@ -19,23 +8,29 @@ notifications:
|
|
19
8
|
- secure: "YnHYbTq51ySistjvOxsuNhyg4GLuUffEJstTYeGYXiBF7HG5h43IVYo8KNuLzwkgsOYBcNo+YMdQX7qCqJffSbhsr1FZRSzBmjFFxcyD4hu+ukM2theZ4mePVAZiePscYvQPRNY4hIb4d3egStJEytkalDhB3sOebF57tIaCssg="
|
20
9
|
rvm:
|
21
10
|
- 2.2.10
|
22
|
-
- 2.3.
|
23
|
-
- 2.4.
|
24
|
-
- 2.5.
|
11
|
+
- 2.3.8
|
12
|
+
- 2.4.9
|
13
|
+
- 2.5.7
|
14
|
+
- 2.6.5
|
15
|
+
- 2.7.0
|
25
16
|
- ruby-head
|
17
|
+
- truffleruby-head
|
26
18
|
gemfile:
|
27
19
|
- gemfiles/rails42.gemfile
|
28
20
|
- gemfiles/rails50.gemfile
|
29
21
|
- gemfiles/rails51.gemfile
|
30
22
|
- gemfiles/rails52.gemfile
|
23
|
+
- gemfiles/rails60.gemfile
|
31
24
|
- gemfiles/rails42_haml.gemfile
|
32
25
|
- gemfiles/rails50_haml.gemfile
|
33
26
|
- gemfiles/rails51_haml.gemfile
|
34
27
|
- gemfiles/rails52_haml.gemfile
|
28
|
+
- gemfiles/rails60_haml.gemfile
|
35
29
|
- gemfiles/rails42_boc.gemfile
|
36
30
|
- gemfiles/rails50_boc.gemfile
|
37
31
|
- gemfiles/rails51_boc.gemfile
|
38
32
|
- gemfiles/rails52_boc.gemfile
|
33
|
+
- gemfiles/rails60_boc.gemfile
|
39
34
|
- gemfiles/rack.gemfile
|
40
35
|
- gemfiles/rack_boc.gemfile
|
41
36
|
- gemfiles/pry09.gemfile
|
@@ -48,15 +43,69 @@ matrix:
|
|
48
43
|
- gemfile: gemfiles/pry010.gemfile
|
49
44
|
- gemfile: gemfiles/pry011.gemfile
|
50
45
|
exclude:
|
51
|
-
- rvm: 2.
|
46
|
+
- rvm: 2.2.10
|
47
|
+
gemfile: gemfiles/rails60.gemfile
|
48
|
+
- rvm: 2.2.10
|
49
|
+
gemfile: gemfiles/rails60_boc.gemfile
|
50
|
+
- rvm: 2.2.10
|
51
|
+
gemfile: gemfiles/rails60_haml.gemfile
|
52
|
+
- rvm: 2.3.8
|
52
53
|
gemfile: gemfiles/rails42.gemfile
|
53
|
-
- rvm: 2.
|
54
|
+
- rvm: 2.3.8
|
54
55
|
gemfile: gemfiles/rails42_boc.gemfile
|
55
|
-
- rvm: 2.
|
56
|
+
- rvm: 2.3.8
|
56
57
|
gemfile: gemfiles/rails42_haml.gemfile
|
57
|
-
- rvm: 2.
|
58
|
+
- rvm: 2.3.8
|
59
|
+
gemfile: gemfiles/rails60.gemfile
|
60
|
+
- rvm: 2.3.8
|
61
|
+
gemfile: gemfiles/rails60_boc.gemfile
|
62
|
+
- rvm: 2.3.8
|
63
|
+
gemfile: gemfiles/rails60_haml.gemfile
|
64
|
+
- rvm: 2.4.9
|
58
65
|
gemfile: gemfiles/rails42.gemfile
|
59
|
-
- rvm: 2.
|
66
|
+
- rvm: 2.4.9
|
60
67
|
gemfile: gemfiles/rails42_boc.gemfile
|
61
|
-
- rvm: 2.
|
68
|
+
- rvm: 2.4.9
|
62
69
|
gemfile: gemfiles/rails42_haml.gemfile
|
70
|
+
- rvm: 2.4.9
|
71
|
+
gemfile: gemfiles/rails60.gemfile
|
72
|
+
- rvm: 2.4.9
|
73
|
+
gemfile: gemfiles/rails60_boc.gemfile
|
74
|
+
- rvm: 2.4.9
|
75
|
+
gemfile: gemfiles/rails60_haml.gemfile
|
76
|
+
- rvm: 2.5.7
|
77
|
+
gemfile: gemfiles/rails42.gemfile
|
78
|
+
- rvm: 2.5.7
|
79
|
+
gemfile: gemfiles/rails42_boc.gemfile
|
80
|
+
- rvm: 2.5.7
|
81
|
+
gemfile: gemfiles/rails42_haml.gemfile
|
82
|
+
- rvm: 2.6.5
|
83
|
+
gemfile: gemfiles/rails42.gemfile
|
84
|
+
- rvm: 2.6.5
|
85
|
+
gemfile: gemfiles/rails42_boc.gemfile
|
86
|
+
- rvm: 2.6.5
|
87
|
+
gemfile: gemfiles/rails42_haml.gemfile
|
88
|
+
- rvm: 2.7.0
|
89
|
+
gemfile: gemfiles/rails42.gemfile
|
90
|
+
- rvm: 2.7.0
|
91
|
+
gemfile: gemfiles/rails42_boc.gemfile
|
92
|
+
- rvm: 2.7.0
|
93
|
+
gemfile: gemfiles/rails42_haml.gemfile
|
94
|
+
- rvm: ruby-head
|
95
|
+
gemfile: gemfiles/rails42.gemfile
|
96
|
+
- rvm: ruby-head
|
97
|
+
gemfile: gemfiles/rails42_boc.gemfile
|
98
|
+
- rvm: ruby-head
|
99
|
+
gemfile: gemfiles/rails42_haml.gemfile
|
100
|
+
- rvm: truffleruby-head
|
101
|
+
gemfile: gemfiles/rails42_boc.gemfile
|
102
|
+
- rvm: truffleruby-head
|
103
|
+
gemfile: gemfiles/rails50_boc.gemfile
|
104
|
+
- rvm: truffleruby-head
|
105
|
+
gemfile: gemfiles/rails51_boc.gemfile
|
106
|
+
- rvm: truffleruby-head
|
107
|
+
gemfile: gemfiles/rails52_boc.gemfile
|
108
|
+
- rvm: truffleruby-head
|
109
|
+
gemfile: gemfiles/rails60_boc.gemfile
|
110
|
+
- rvm: truffleruby-head
|
111
|
+
gemfile: gemfiles/rack_boc.gemfile
|
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,11 @@ 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')
|
28
30
|
# simplecov and coveralls must not be included here. See the Gemfiles instead.
|
29
31
|
|
30
32
|
s.add_dependency "erubi", ">= 1.0.0"
|
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,7 +122,13 @@ 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
133
|
"<span class='unsupported'>(Object too large. "\
|
111
134
|
"#{obj.class.name ? "Modify #{CGI.escapeHTML(obj.class.name)}#inspect or a" : "A"}"\
|
@@ -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,18 @@ module BetterErrors
|
|
4
4
|
attr_reader :exception, :message, :backtrace
|
5
5
|
|
6
6
|
def initialize(exception)
|
7
|
-
if exception.respond_to?(:cause)
|
7
|
+
if exception.class.name == "ActionView::Template::Error" && exception.respond_to?(:cause)
|
8
|
+
# Rails 6+ exceptions of this type wrap the "real" exception, and the real exception
|
9
|
+
# is actually more useful than the ActionView-provided wrapper. Once Better Errors
|
10
|
+
# supports showing all exceptions in the cause stack, this should go away. Or perhaps
|
11
|
+
# this can be changed to provide guidance by showing the second error in the cause stack
|
12
|
+
# under this condition.
|
8
13
|
exception = exception.cause if exception.cause
|
9
14
|
elsif exception.respond_to?(:original_exception) && exception.original_exception
|
15
|
+
# This supports some specific Rails exceptions, and this is not intended to act the same as
|
16
|
+
# the Ruby's {Exception#cause}.
|
17
|
+
# It's possible this should only support ActionView::Template::Error, but by not changing
|
18
|
+
# this we're preserving longstanding behavior of Better Errors with Rails < 6.
|
10
19
|
exception = exception.original_exception
|
11
20
|
end
|
12
21
|
|
@@ -36,8 +45,13 @@ module BetterErrors
|
|
36
45
|
|
37
46
|
def setup_backtrace_from_bindings
|
38
47
|
@backtrace = exception.__better_errors_bindings_stack.map { |binding|
|
39
|
-
|
40
|
-
|
48
|
+
if binding.respond_to?(:source_location) # Ruby >= 2.6
|
49
|
+
file = binding.source_location[0]
|
50
|
+
line = binding.source_location[1]
|
51
|
+
else
|
52
|
+
file = binding.eval "__FILE__"
|
53
|
+
line = binding.eval "__LINE__"
|
54
|
+
end
|
41
55
|
name = binding.frame_description
|
42
56
|
StackFrame.new(file, line, name, binding)
|
43
57
|
}
|
@@ -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.1
|
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-17 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
|
@@ -197,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
214
|
- !ruby/object:Gem::Version
|
198
215
|
version: '0'
|
199
216
|
requirements: []
|
200
|
-
rubygems_version: 3.
|
217
|
+
rubygems_version: 3.1.2
|
201
218
|
signing_key:
|
202
219
|
specification_version: 4
|
203
220
|
summary: Better error page for Rails and other Rack apps
|