better_errors 2.5.1 → 2.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +130 -0
- data/.github/workflows/release.yml +64 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -1
- data/README.md +34 -2
- data/better_errors.gemspec +3 -1
- data/gemfiles/pry010.gemfile +2 -1
- data/gemfiles/pry011.gemfile +2 -1
- data/gemfiles/pry09.gemfile +2 -1
- data/gemfiles/rack.gemfile +2 -1
- data/gemfiles/rack_boc.gemfile +2 -1
- data/gemfiles/rails42.gemfile +3 -1
- data/gemfiles/rails42_boc.gemfile +3 -1
- data/gemfiles/rails42_haml.gemfile +3 -1
- data/gemfiles/rails50.gemfile +3 -1
- data/gemfiles/rails50_boc.gemfile +3 -1
- data/gemfiles/rails50_haml.gemfile +3 -1
- data/gemfiles/rails51.gemfile +3 -1
- data/gemfiles/rails51_boc.gemfile +3 -1
- data/gemfiles/rails51_haml.gemfile +3 -1
- data/gemfiles/rails52.gemfile +3 -1
- data/gemfiles/rails52_boc.gemfile +3 -1
- data/gemfiles/rails52_haml.gemfile +3 -1
- data/gemfiles/rails60.gemfile +8 -0
- data/gemfiles/rails60_boc.gemfile +9 -0
- data/gemfiles/rails60_haml.gemfile +9 -0
- data/lib/better_errors.rb +20 -33
- data/lib/better_errors/editor.rb +99 -0
- data/lib/better_errors/error_page.rb +31 -4
- data/lib/better_errors/exception_hint.rb +29 -0
- data/lib/better_errors/middleware.rb +59 -12
- data/lib/better_errors/raised_exception.rb +25 -4
- data/lib/better_errors/stack_frame.rb +8 -2
- data/lib/better_errors/templates/main.erb +61 -17
- data/lib/better_errors/templates/text.erb +5 -2
- data/lib/better_errors/templates/variable_info.erb +9 -2
- data/lib/better_errors/version.rb +1 -1
- metadata +28 -7
- data/.travis.yml +0 -62
@@ -1,12 +1,23 @@
|
|
1
|
+
require 'better_errors/exception_hint'
|
2
|
+
|
1
3
|
# @private
|
2
4
|
module BetterErrors
|
3
5
|
class RaisedException
|
4
|
-
attr_reader :exception, :message, :backtrace
|
6
|
+
attr_reader :exception, :message, :backtrace, :hint
|
5
7
|
|
6
8
|
def initialize(exception)
|
7
|
-
if exception.respond_to?(:cause)
|
9
|
+
if exception.class.name == "ActionView::Template::Error" && exception.respond_to?(:cause)
|
10
|
+
# Rails 6+ exceptions of this type wrap the "real" exception, and the real exception
|
11
|
+
# is actually more useful than the ActionView-provided wrapper. Once Better Errors
|
12
|
+
# supports showing all exceptions in the cause stack, this should go away. Or perhaps
|
13
|
+
# this can be changed to provide guidance by showing the second error in the cause stack
|
14
|
+
# under this condition.
|
8
15
|
exception = exception.cause if exception.cause
|
9
16
|
elsif exception.respond_to?(:original_exception) && exception.original_exception
|
17
|
+
# This supports some specific Rails exceptions, and this is not intended to act the same as
|
18
|
+
# the Ruby's {Exception#cause}.
|
19
|
+
# It's possible this should only support ActionView::Template::Error, but by not changing
|
20
|
+
# this we're preserving longstanding behavior of Better Errors with Rails < 6.
|
10
21
|
exception = exception.original_exception
|
11
22
|
end
|
12
23
|
|
@@ -14,6 +25,7 @@ module BetterErrors
|
|
14
25
|
@message = exception.message
|
15
26
|
|
16
27
|
setup_backtrace
|
28
|
+
setup_hint
|
17
29
|
massage_syntax_error
|
18
30
|
end
|
19
31
|
|
@@ -36,8 +48,13 @@ module BetterErrors
|
|
36
48
|
|
37
49
|
def setup_backtrace_from_bindings
|
38
50
|
@backtrace = exception.__better_errors_bindings_stack.map { |binding|
|
39
|
-
|
40
|
-
|
51
|
+
if binding.respond_to?(:source_location) # Ruby >= 2.6
|
52
|
+
file = binding.source_location[0]
|
53
|
+
line = binding.source_location[1]
|
54
|
+
else
|
55
|
+
file = binding.eval "__FILE__"
|
56
|
+
line = binding.eval "__LINE__"
|
57
|
+
end
|
41
58
|
name = binding.frame_description
|
42
59
|
StackFrame.new(file, line, name, binding)
|
43
60
|
}
|
@@ -64,5 +81,9 @@ module BetterErrors
|
|
64
81
|
end
|
65
82
|
end
|
66
83
|
end
|
84
|
+
|
85
|
+
def setup_hint
|
86
|
+
@hint = ExceptionHint.new(exception).hint
|
87
|
+
end
|
67
88
|
end
|
68
89
|
end
|
@@ -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
|
@@ -90,7 +90,7 @@
|
|
90
90
|
nav.sidebar,
|
91
91
|
.frame_info {
|
92
92
|
position: fixed;
|
93
|
-
top:
|
93
|
+
top: 102px;
|
94
94
|
bottom: 0;
|
95
95
|
|
96
96
|
box-sizing: border-box;
|
@@ -102,7 +102,7 @@
|
|
102
102
|
nav.sidebar {
|
103
103
|
width: 40%;
|
104
104
|
left: 20px;
|
105
|
-
top:
|
105
|
+
top: 122px;
|
106
106
|
bottom: 20px;
|
107
107
|
}
|
108
108
|
|
@@ -131,7 +131,7 @@
|
|
131
131
|
header.exception {
|
132
132
|
padding: 18px 20px;
|
133
133
|
|
134
|
-
height:
|
134
|
+
height: 66px;
|
135
135
|
min-height: 59px;
|
136
136
|
|
137
137
|
overflow: hidden;
|
@@ -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
|
|
@@ -587,6 +595,9 @@
|
|
587
595
|
color: #8080a0;
|
588
596
|
padding-left: 20px;
|
589
597
|
}
|
598
|
+
.console-has-been-used .live-console-hint {
|
599
|
+
display: none;
|
600
|
+
}
|
590
601
|
|
591
602
|
.hint:before {
|
592
603
|
content: '\25b2';
|
@@ -603,17 +614,6 @@
|
|
603
614
|
margin: 10px 0;
|
604
615
|
}
|
605
616
|
|
606
|
-
.sub:before {
|
607
|
-
content: '';
|
608
|
-
display: block;
|
609
|
-
width: 100%;
|
610
|
-
height: 4px;
|
611
|
-
|
612
|
-
border-radius: 2px;
|
613
|
-
background: rgba(0, 150, 200, 0.05);
|
614
|
-
box-shadow: 1px 1px 0 rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04), inset 2px 2px 2px rgba(0, 0, 0, 0.07);
|
615
|
-
}
|
616
|
-
|
617
617
|
.sub h3 {
|
618
618
|
color: #39a;
|
619
619
|
font-size: 1.1em;
|
@@ -744,6 +744,21 @@
|
|
744
744
|
<header class="exception">
|
745
745
|
<h2><strong><%= exception_type %></strong> <span>at <%= request_path %></span></h2>
|
746
746
|
<p><%= exception_message %></p>
|
747
|
+
<% unless active_support_actions.empty? %>
|
748
|
+
<div class='fix-actions'>
|
749
|
+
<% active_support_actions.each do |action, _| %>
|
750
|
+
<form class="button_to" method="post" action="<%= action_dispatch_action_endpoint %>">
|
751
|
+
<input type="submit" value="<%= action %>">
|
752
|
+
<input type="hidden" name="action" value="<%= action %>">
|
753
|
+
<input type="hidden" name="error" value="<%= exception_type %>">
|
754
|
+
<input type="hidden" name="location" value="<%= request_path %>">
|
755
|
+
</form>
|
756
|
+
<% end %>
|
757
|
+
</div>
|
758
|
+
<% end %>
|
759
|
+
<% if exception_hint %>
|
760
|
+
<h2>Hint: <%= exception_hint %></h2>
|
761
|
+
<% end %>
|
747
762
|
</header>
|
748
763
|
</div>
|
749
764
|
|
@@ -780,6 +795,7 @@
|
|
780
795
|
(function() {
|
781
796
|
|
782
797
|
var OID = "<%= id %>";
|
798
|
+
var csrfToken = "<%= csrf_token %>";
|
783
799
|
|
784
800
|
var previousFrame = null;
|
785
801
|
var previousFrameInfo = null;
|
@@ -790,6 +806,7 @@
|
|
790
806
|
var req = new XMLHttpRequest();
|
791
807
|
req.open("POST", "//" + window.location.host + <%== uri_prefix.gsub("<", "<").inspect %> + "/__better_errors/" + OID + "/" + method, true);
|
792
808
|
req.setRequestHeader("Content-Type", "application/json");
|
809
|
+
opts.csrfToken = csrfToken;
|
793
810
|
req.send(JSON.stringify(opts));
|
794
811
|
req.onreadystatechange = function() {
|
795
812
|
if(req.readyState == 4) {
|
@@ -803,6 +820,28 @@
|
|
803
820
|
return html.replace(/&/, "&").replace(/</g, "<");
|
804
821
|
}
|
805
822
|
|
823
|
+
function hasConsoleBeenUsedPreviously() {
|
824
|
+
return !!document.cookie.split('; ').find(function(cookie) {
|
825
|
+
return cookie.startsWith('BetterErrors-has-used-console=');
|
826
|
+
});
|
827
|
+
}
|
828
|
+
|
829
|
+
var consoleHasBeenUsed = hasConsoleBeenUsedPreviously();
|
830
|
+
|
831
|
+
function consoleWasJustUsed() {
|
832
|
+
if (consoleHasBeenUsed) {
|
833
|
+
return;
|
834
|
+
}
|
835
|
+
|
836
|
+
hideConsoleHint();
|
837
|
+
consoleHasBeenUsed = true;
|
838
|
+
document.cookie = "BetterErrors-has-used-console=true;path=/;max-age=31536000;samesite"
|
839
|
+
}
|
840
|
+
|
841
|
+
function hideConsoleHint() {
|
842
|
+
document.querySelector('body').className += " console-has-been-used";
|
843
|
+
}
|
844
|
+
|
806
845
|
function REPL(index) {
|
807
846
|
this.index = index;
|
808
847
|
|
@@ -824,15 +863,20 @@
|
|
824
863
|
this.inputElement = this.container.querySelector("input");
|
825
864
|
this.outputElement = this.container.querySelector("pre");
|
826
865
|
|
866
|
+
if (consoleHasBeenUsed) {
|
867
|
+
hideConsoleHint();
|
868
|
+
}
|
869
|
+
|
827
870
|
var self = this;
|
828
871
|
this.inputElement.onkeydown = function(ev) {
|
829
872
|
self.onKeyDown(ev);
|
873
|
+
consoleWasJustUsed();
|
830
874
|
};
|
831
875
|
|
832
876
|
this.setPrompt(">>");
|
833
877
|
|
834
878
|
REPL.all[this.index] = this;
|
835
|
-
}
|
879
|
+
};
|
836
880
|
|
837
881
|
REPL.prototype.focus = function() {
|
838
882
|
this.inputElement.focus();
|
@@ -1,7 +1,10 @@
|
|
1
1
|
<%== text_heading("=", "%s at %s" % [exception_type, request_path]) %>
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
<%== exception_message %>
|
4
|
+
|
5
|
+
> To access an interactive console with this error, point your browser to: /__better_errors
|
6
|
+
|
7
|
+
<% if backtrace_frames.any? -%>
|
5
8
|
|
6
9
|
<%== text_heading("-", "%s, line %i" % [first_frame.pretty_path, first_frame.line]) %>
|
7
10
|
|
@@ -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 %>
|
@@ -18,7 +25,7 @@
|
|
18
25
|
</header>
|
19
26
|
|
20
27
|
<% if BetterErrors.binding_of_caller_available? && @frame.frame_binding %>
|
21
|
-
<div class="hint">
|
28
|
+
<div class="hint live-console-hint">
|
22
29
|
This is a live shell. Type in here.
|
23
30
|
</div>
|
24
31
|
|
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.9.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-11-05 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
|
@@ -132,8 +146,10 @@ extensions: []
|
|
132
146
|
extra_rdoc_files: []
|
133
147
|
files:
|
134
148
|
- ".coveralls.yml"
|
149
|
+
- ".github/workflows/ci.yml"
|
150
|
+
- ".github/workflows/release.yml"
|
135
151
|
- ".gitignore"
|
136
|
-
- ".
|
152
|
+
- ".ruby-version"
|
137
153
|
- ".yardopts"
|
138
154
|
- CHANGELOG.md
|
139
155
|
- Gemfile
|
@@ -157,12 +173,17 @@ files:
|
|
157
173
|
- gemfiles/rails52.gemfile
|
158
174
|
- gemfiles/rails52_boc.gemfile
|
159
175
|
- gemfiles/rails52_haml.gemfile
|
176
|
+
- gemfiles/rails60.gemfile
|
177
|
+
- gemfiles/rails60_boc.gemfile
|
178
|
+
- gemfiles/rails60_haml.gemfile
|
160
179
|
- lib/better_errors.rb
|
161
180
|
- lib/better_errors/code_formatter.rb
|
162
181
|
- lib/better_errors/code_formatter/html.rb
|
163
182
|
- lib/better_errors/code_formatter/text.rb
|
183
|
+
- lib/better_errors/editor.rb
|
164
184
|
- lib/better_errors/error_page.rb
|
165
185
|
- lib/better_errors/exception_extension.rb
|
186
|
+
- lib/better_errors/exception_hint.rb
|
166
187
|
- lib/better_errors/inspectable_value.rb
|
167
188
|
- lib/better_errors/middleware.rb
|
168
189
|
- lib/better_errors/rails.rb
|
@@ -197,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
218
|
- !ruby/object:Gem::Version
|
198
219
|
version: '0'
|
199
220
|
requirements: []
|
200
|
-
rubygems_version: 3.
|
221
|
+
rubygems_version: 3.1.4
|
201
222
|
signing_key:
|
202
223
|
specification_version: 4
|
203
224
|
summary: Better error page for Rails and other Rack apps
|
data/.travis.yml
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
language: ruby
|
3
|
-
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
|
-
notifications:
|
15
|
-
webhooks:
|
16
|
-
# With COVERALLS_PARALLEL, coverage information sent to coveralls will not be processed until
|
17
|
-
# this webhook is sent.
|
18
|
-
# https://coveralls.zendesk.com/hc/en-us/articles/203484329-Parallel-Build-Webhook
|
19
|
-
- secure: "YnHYbTq51ySistjvOxsuNhyg4GLuUffEJstTYeGYXiBF7HG5h43IVYo8KNuLzwkgsOYBcNo+YMdQX7qCqJffSbhsr1FZRSzBmjFFxcyD4hu+ukM2theZ4mePVAZiePscYvQPRNY4hIb4d3egStJEytkalDhB3sOebF57tIaCssg="
|
20
|
-
rvm:
|
21
|
-
- 2.2.10
|
22
|
-
- 2.3.7
|
23
|
-
- 2.4.4
|
24
|
-
- 2.5.1
|
25
|
-
- ruby-head
|
26
|
-
gemfile:
|
27
|
-
- gemfiles/rails42.gemfile
|
28
|
-
- gemfiles/rails50.gemfile
|
29
|
-
- gemfiles/rails51.gemfile
|
30
|
-
- gemfiles/rails52.gemfile
|
31
|
-
- gemfiles/rails42_haml.gemfile
|
32
|
-
- gemfiles/rails50_haml.gemfile
|
33
|
-
- gemfiles/rails51_haml.gemfile
|
34
|
-
- gemfiles/rails52_haml.gemfile
|
35
|
-
- gemfiles/rails42_boc.gemfile
|
36
|
-
- gemfiles/rails50_boc.gemfile
|
37
|
-
- gemfiles/rails51_boc.gemfile
|
38
|
-
- gemfiles/rails52_boc.gemfile
|
39
|
-
- gemfiles/rack.gemfile
|
40
|
-
- gemfiles/rack_boc.gemfile
|
41
|
-
- gemfiles/pry09.gemfile
|
42
|
-
- gemfiles/pry010.gemfile
|
43
|
-
- gemfiles/pry011.gemfile
|
44
|
-
matrix:
|
45
|
-
fast_finish: true
|
46
|
-
allow_failures:
|
47
|
-
- rvm: ruby-head
|
48
|
-
- gemfile: gemfiles/pry010.gemfile
|
49
|
-
- gemfile: gemfiles/pry011.gemfile
|
50
|
-
exclude:
|
51
|
-
- rvm: 2.4.4
|
52
|
-
gemfile: gemfiles/rails42.gemfile
|
53
|
-
- rvm: 2.4.4
|
54
|
-
gemfile: gemfiles/rails42_boc.gemfile
|
55
|
-
- rvm: 2.4.4
|
56
|
-
gemfile: gemfiles/rails42_haml.gemfile
|
57
|
-
- rvm: 2.5.1
|
58
|
-
gemfile: gemfiles/rails42.gemfile
|
59
|
-
- rvm: 2.5.1
|
60
|
-
gemfile: gemfiles/rails42_boc.gemfile
|
61
|
-
- rvm: 2.5.1
|
62
|
-
gemfile: gemfiles/rails42_haml.gemfile
|