better_errors 1.0.0 → 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 +5 -5
- data/.coveralls.yml +1 -0
- data/.github/workflows/ci.yml +130 -0
- data/.github/workflows/release.yml +64 -0
- data/.gitignore +10 -5
- data/.ruby-version +1 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +7 -7
- data/LICENSE.txt +1 -1
- data/README.md +103 -33
- data/better_errors.gemspec +26 -8
- data/gemfiles/pry010.gemfile +10 -0
- data/gemfiles/pry011.gemfile +9 -0
- data/gemfiles/pry09.gemfile +9 -0
- data/gemfiles/rack.gemfile +8 -0
- data/gemfiles/rack_boc.gemfile +9 -0
- data/gemfiles/rails42.gemfile +10 -0
- data/gemfiles/rails42_boc.gemfile +11 -0
- data/gemfiles/rails42_haml.gemfile +11 -0
- data/gemfiles/rails50.gemfile +9 -0
- data/gemfiles/rails50_boc.gemfile +10 -0
- data/gemfiles/rails50_haml.gemfile +10 -0
- data/gemfiles/rails51.gemfile +9 -0
- data/gemfiles/rails51_boc.gemfile +10 -0
- data/gemfiles/rails51_haml.gemfile +10 -0
- data/gemfiles/rails52.gemfile +9 -0
- data/gemfiles/rails52_boc.gemfile +10 -0
- data/gemfiles/rails52_haml.gemfile +10 -0
- data/gemfiles/rails60.gemfile +8 -0
- data/gemfiles/rails60_boc.gemfile +9 -0
- data/gemfiles/rails60_haml.gemfile +9 -0
- data/lib/better_errors/code_formatter/html.rb +1 -1
- data/lib/better_errors/code_formatter.rb +7 -7
- data/lib/better_errors/editor.rb +99 -0
- data/lib/better_errors/error_page.rb +83 -49
- data/lib/better_errors/exception_extension.rb +17 -0
- data/lib/better_errors/exception_hint.rb +29 -0
- data/lib/better_errors/inspectable_value.rb +45 -0
- data/lib/better_errors/middleware.rb +101 -21
- data/lib/better_errors/raised_exception.rb +89 -0
- data/lib/better_errors/repl/basic.rb +3 -3
- data/lib/better_errors/repl/pry.rb +20 -10
- data/lib/better_errors/repl.rb +6 -4
- data/lib/better_errors/stack_frame.rb +48 -71
- data/lib/better_errors/templates/main.erb +167 -94
- data/lib/better_errors/templates/text.erb +6 -3
- data/lib/better_errors/templates/variable_info.erb +33 -24
- data/lib/better_errors/version.rb +1 -1
- data/lib/better_errors.rb +35 -37
- metadata +150 -46
- data/.travis.yml +0 -6
- data/Rakefile +0 -4
- data/ext/mkrf_conf.rb +0 -11
- data/lib/better_errors/core_ext/exception.rb +0 -21
- data/spec/better_errors/code_formatter_spec.rb +0 -92
- data/spec/better_errors/error_page_spec.rb +0 -76
- data/spec/better_errors/middleware_spec.rb +0 -112
- data/spec/better_errors/repl/basic_spec.rb +0 -18
- data/spec/better_errors/repl/pry_spec.rb +0 -36
- data/spec/better_errors/repl/shared_examples.rb +0 -18
- data/spec/better_errors/stack_frame_spec.rb +0 -161
- data/spec/better_errors/support/my_source.rb +0 -20
- data/spec/better_errors_spec.rb +0 -73
- data/spec/spec_helper.rb +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
|
-
<title><%=
|
|
4
|
+
<title><%= exception_type %> at <%= request_path %></title>
|
|
5
5
|
</head>
|
|
6
6
|
<body>
|
|
7
7
|
<%# Stylesheets are placed in the <body> for Turbolinks compatibility. %>
|
|
@@ -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
|
|
|
@@ -180,8 +188,9 @@
|
|
|
180
188
|
padding-right: 20px;
|
|
181
189
|
overflow-y: auto;
|
|
182
190
|
word-wrap: break-word;
|
|
191
|
+
white-space: pre-wrap;
|
|
183
192
|
height: auto;
|
|
184
|
-
max-height:
|
|
193
|
+
max-height: 7.5em;
|
|
185
194
|
}
|
|
186
195
|
|
|
187
196
|
@media screen and (max-width: 1100px) {
|
|
@@ -393,7 +402,7 @@
|
|
|
393
402
|
* Monospace
|
|
394
403
|
* --------------------------------------------------------------------- */
|
|
395
404
|
|
|
396
|
-
pre, code, .repl input, .repl .
|
|
405
|
+
pre, code, .be-repl input, .be-repl .command-line span, textarea, .code_linenums {
|
|
397
406
|
font-family: menlo, lucida console, monospace;
|
|
398
407
|
font-size: 8pt;
|
|
399
408
|
}
|
|
@@ -443,13 +452,13 @@
|
|
|
443
452
|
font-weight: bold;
|
|
444
453
|
font-size: 10pt;
|
|
445
454
|
}
|
|
446
|
-
|
|
455
|
+
|
|
447
456
|
.trace_info .title .location a {
|
|
448
457
|
color:inherit;
|
|
449
458
|
text-decoration:none;
|
|
450
459
|
border-bottom:1px solid #aaaaaa;
|
|
451
460
|
}
|
|
452
|
-
|
|
461
|
+
|
|
453
462
|
.trace_info .title .location a:hover {
|
|
454
463
|
border-color:#666666;
|
|
455
464
|
}
|
|
@@ -459,7 +468,7 @@
|
|
|
459
468
|
font-weight: 200;
|
|
460
469
|
}
|
|
461
470
|
|
|
462
|
-
.code, .console, .unavailable {
|
|
471
|
+
.code, .be-console, .unavailable {
|
|
463
472
|
background: #fff;
|
|
464
473
|
padding: 5px;
|
|
465
474
|
|
|
@@ -472,7 +481,7 @@
|
|
|
472
481
|
padding-bottom:9px;
|
|
473
482
|
float:left;
|
|
474
483
|
}
|
|
475
|
-
|
|
484
|
+
|
|
476
485
|
.code_linenums span{
|
|
477
486
|
display:block;
|
|
478
487
|
padding:0 12px;
|
|
@@ -531,13 +540,13 @@
|
|
|
531
540
|
}
|
|
532
541
|
|
|
533
542
|
/* REPL shell */
|
|
534
|
-
.console {
|
|
543
|
+
.be-console {
|
|
535
544
|
padding: 0 1px 10px 1px;
|
|
536
545
|
border-bottom-left-radius: 2px;
|
|
537
546
|
border-bottom-right-radius: 2px;
|
|
538
547
|
}
|
|
539
548
|
|
|
540
|
-
.console pre {
|
|
549
|
+
.be-console pre {
|
|
541
550
|
padding: 10px 10px 0 10px;
|
|
542
551
|
max-height: 400px;
|
|
543
552
|
overflow-x: none;
|
|
@@ -547,30 +556,31 @@
|
|
|
547
556
|
white-space: pre-wrap;
|
|
548
557
|
}
|
|
549
558
|
|
|
550
|
-
/* .
|
|
551
|
-
.console .
|
|
559
|
+
/* .command-line > span + input */
|
|
560
|
+
.be-console .command-line {
|
|
552
561
|
display: table;
|
|
553
562
|
width: 100%;
|
|
554
563
|
}
|
|
555
564
|
|
|
556
|
-
.console .
|
|
557
|
-
.console .
|
|
565
|
+
.be-console .command-line span,
|
|
566
|
+
.be-console .command-line input {
|
|
558
567
|
display: table-cell;
|
|
559
568
|
}
|
|
560
569
|
|
|
561
|
-
.console .
|
|
570
|
+
.be-console .command-line span {
|
|
562
571
|
width: 1%;
|
|
563
572
|
padding-right: 5px;
|
|
564
573
|
padding-left: 10px;
|
|
574
|
+
white-space: pre;
|
|
565
575
|
}
|
|
566
576
|
|
|
567
|
-
.console .
|
|
577
|
+
.be-console .command-line input {
|
|
568
578
|
width: 99%;
|
|
569
579
|
}
|
|
570
580
|
|
|
571
581
|
/* Input box */
|
|
572
|
-
.console input,
|
|
573
|
-
.console input:focus {
|
|
582
|
+
.be-console input,
|
|
583
|
+
.be-console input:focus {
|
|
574
584
|
outline: 0;
|
|
575
585
|
border: 0;
|
|
576
586
|
padding: 0;
|
|
@@ -585,6 +595,9 @@
|
|
|
585
595
|
color: #8080a0;
|
|
586
596
|
padding-left: 20px;
|
|
587
597
|
}
|
|
598
|
+
.console-has-been-used .live-console-hint {
|
|
599
|
+
display: none;
|
|
600
|
+
}
|
|
588
601
|
|
|
589
602
|
.hint:before {
|
|
590
603
|
content: '\25b2';
|
|
@@ -601,17 +614,6 @@
|
|
|
601
614
|
margin: 10px 0;
|
|
602
615
|
}
|
|
603
616
|
|
|
604
|
-
.sub:before {
|
|
605
|
-
content: '';
|
|
606
|
-
display: block;
|
|
607
|
-
width: 100%;
|
|
608
|
-
height: 4px;
|
|
609
|
-
|
|
610
|
-
border-radius: 2px;
|
|
611
|
-
background: rgba(0, 150, 200, 0.05);
|
|
612
|
-
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);
|
|
613
|
-
}
|
|
614
|
-
|
|
615
617
|
.sub h3 {
|
|
616
618
|
color: #39a;
|
|
617
619
|
font-size: 1.1em;
|
|
@@ -668,14 +670,14 @@
|
|
|
668
670
|
|
|
669
671
|
nav.sidebar::-webkit-scrollbar,
|
|
670
672
|
.inset pre::-webkit-scrollbar,
|
|
671
|
-
.console pre::-webkit-scrollbar,
|
|
673
|
+
.be-console pre::-webkit-scrollbar,
|
|
672
674
|
.code::-webkit-scrollbar {
|
|
673
675
|
width: 10px;
|
|
674
676
|
height: 10px;
|
|
675
677
|
}
|
|
676
678
|
|
|
677
679
|
.inset pre::-webkit-scrollbar-thumb,
|
|
678
|
-
.console pre::-webkit-scrollbar-thumb,
|
|
680
|
+
.be-console pre::-webkit-scrollbar-thumb,
|
|
679
681
|
.code::-webkit-scrollbar-thumb {
|
|
680
682
|
background: #ccc;
|
|
681
683
|
border-radius: 5px;
|
|
@@ -691,7 +693,7 @@
|
|
|
691
693
|
background: -webkit-linear-gradient(left, #aaa, #999);
|
|
692
694
|
}
|
|
693
695
|
|
|
694
|
-
.console pre:hover::-webkit-scrollbar-thumb,
|
|
696
|
+
.be-console pre:hover::-webkit-scrollbar-thumb,
|
|
695
697
|
.inset pre:hover::-webkit-scrollbar-thumb,
|
|
696
698
|
.code:hover::-webkit-scrollbar-thumb {
|
|
697
699
|
background: #888;
|
|
@@ -719,19 +721,44 @@
|
|
|
719
721
|
if(document.styleSheets[i].href)
|
|
720
722
|
document.styleSheets[i].disabled = true;
|
|
721
723
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
724
|
+
if (window.Turbolinks.controller) {
|
|
725
|
+
// Turbolinks > 5 (see https://github.com/turbolinks/turbolinks/issues/6)
|
|
726
|
+
document.addEventListener("turbolinks:load", function restoreCSS(e) {
|
|
727
|
+
for(var i=0; i < document.styleSheets.length; i++) {
|
|
728
|
+
document.styleSheets[i].disabled = false;
|
|
729
|
+
}
|
|
730
|
+
document.removeEventListener("turbolinks:load", restoreCSS, false);
|
|
731
|
+
});
|
|
732
|
+
} else {
|
|
733
|
+
document.addEventListener("page:restore", function restoreCSS(e) {
|
|
734
|
+
for(var i=0; i < document.styleSheets.length; i++) {
|
|
735
|
+
document.styleSheets[i].disabled = false;
|
|
736
|
+
}
|
|
737
|
+
document.removeEventListener("page:restore", restoreCSS, false);
|
|
738
|
+
});
|
|
739
|
+
}
|
|
728
740
|
}
|
|
729
741
|
</script>
|
|
730
742
|
|
|
731
743
|
<div class='top'>
|
|
732
744
|
<header class="exception">
|
|
733
|
-
<h2><strong><%=
|
|
745
|
+
<h2><strong><%= exception_type %></strong> <span>at <%= request_path %></span></h2>
|
|
734
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 %>
|
|
735
762
|
</header>
|
|
736
763
|
</div>
|
|
737
764
|
|
|
@@ -767,8 +794,9 @@
|
|
|
767
794
|
<script>
|
|
768
795
|
(function() {
|
|
769
796
|
|
|
770
|
-
var OID =
|
|
771
|
-
|
|
797
|
+
var OID = "<%= id %>";
|
|
798
|
+
var csrfToken = "<%= csrf_token %>";
|
|
799
|
+
|
|
772
800
|
var previousFrame = null;
|
|
773
801
|
var previousFrameInfo = null;
|
|
774
802
|
var allFrames = document.querySelectorAll("ul.frames li");
|
|
@@ -776,8 +804,9 @@
|
|
|
776
804
|
|
|
777
805
|
function apiCall(method, opts, cb) {
|
|
778
806
|
var req = new XMLHttpRequest();
|
|
779
|
-
req.open("POST", <%== uri_prefix.gsub("<", "<").inspect %> + "/__better_errors/" + OID + "/" + method, true);
|
|
807
|
+
req.open("POST", "//" + window.location.host + <%== uri_prefix.gsub("<", "<").inspect %> + "/__better_errors/" + OID + "/" + method, true);
|
|
780
808
|
req.setRequestHeader("Content-Type", "application/json");
|
|
809
|
+
opts.csrfToken = csrfToken;
|
|
781
810
|
req.send(JSON.stringify(opts));
|
|
782
811
|
req.onreadystatechange = function() {
|
|
783
812
|
if(req.readyState == 4) {
|
|
@@ -786,68 +815,100 @@
|
|
|
786
815
|
}
|
|
787
816
|
};
|
|
788
817
|
}
|
|
789
|
-
|
|
818
|
+
|
|
790
819
|
function escapeHTML(html) {
|
|
791
820
|
return html.replace(/&/, "&").replace(/</g, "<");
|
|
792
821
|
}
|
|
793
|
-
|
|
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
|
+
|
|
794
845
|
function REPL(index) {
|
|
795
846
|
this.index = index;
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
847
|
+
|
|
848
|
+
var previousCommands = JSON.parse(localStorage.getItem("better_errors_previous_commands"));
|
|
849
|
+
if(previousCommands === null) {
|
|
850
|
+
localStorage.setItem("better_errors_previous_commands", JSON.stringify([]));
|
|
851
|
+
previousCommands = [];
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
this.previousCommandOffset = previousCommands.length;
|
|
799
855
|
}
|
|
800
|
-
|
|
856
|
+
|
|
801
857
|
REPL.all = [];
|
|
802
|
-
|
|
858
|
+
|
|
803
859
|
REPL.prototype.install = function(containerElement) {
|
|
804
860
|
this.container = containerElement;
|
|
805
|
-
|
|
806
|
-
this.promptElement = this.container.querySelector(".prompt
|
|
861
|
+
|
|
862
|
+
this.promptElement = this.container.querySelector(".command-line .prompt");
|
|
807
863
|
this.inputElement = this.container.querySelector("input");
|
|
808
864
|
this.outputElement = this.container.querySelector("pre");
|
|
809
|
-
|
|
865
|
+
|
|
866
|
+
if (consoleHasBeenUsed) {
|
|
867
|
+
hideConsoleHint();
|
|
868
|
+
}
|
|
869
|
+
|
|
810
870
|
var self = this;
|
|
811
871
|
this.inputElement.onkeydown = function(ev) {
|
|
812
872
|
self.onKeyDown(ev);
|
|
873
|
+
consoleWasJustUsed();
|
|
813
874
|
};
|
|
814
|
-
|
|
875
|
+
|
|
815
876
|
this.setPrompt(">>");
|
|
816
|
-
|
|
877
|
+
|
|
817
878
|
REPL.all[this.index] = this;
|
|
818
|
-
}
|
|
819
|
-
|
|
879
|
+
};
|
|
880
|
+
|
|
820
881
|
REPL.prototype.focus = function() {
|
|
821
882
|
this.inputElement.focus();
|
|
822
883
|
};
|
|
823
|
-
|
|
884
|
+
|
|
824
885
|
REPL.prototype.setPrompt = function(prompt) {
|
|
825
886
|
this._prompt = prompt;
|
|
826
887
|
this.promptElement.innerHTML = escapeHTML(prompt);
|
|
827
888
|
};
|
|
828
|
-
|
|
889
|
+
|
|
829
890
|
REPL.prototype.getInput = function() {
|
|
830
891
|
return this.inputElement.value;
|
|
831
892
|
};
|
|
832
|
-
|
|
893
|
+
|
|
833
894
|
REPL.prototype.setInput = function(text) {
|
|
834
895
|
this.inputElement.value = text;
|
|
835
|
-
|
|
896
|
+
|
|
836
897
|
if(this.inputElement.setSelectionRange) {
|
|
837
898
|
// set cursor to end of input
|
|
838
899
|
this.inputElement.setSelectionRange(text.length, text.length);
|
|
839
900
|
}
|
|
840
901
|
};
|
|
841
|
-
|
|
902
|
+
|
|
842
903
|
REPL.prototype.writeRawOutput = function(output) {
|
|
843
904
|
this.outputElement.innerHTML += output;
|
|
844
905
|
this.outputElement.scrollTop = this.outputElement.scrollHeight;
|
|
845
906
|
};
|
|
846
|
-
|
|
907
|
+
|
|
847
908
|
REPL.prototype.writeOutput = function(output) {
|
|
848
909
|
this.writeRawOutput(escapeHTML(output));
|
|
849
910
|
};
|
|
850
|
-
|
|
911
|
+
|
|
851
912
|
REPL.prototype.sendInput = function(line) {
|
|
852
913
|
var self = this;
|
|
853
914
|
apiCall("eval", { "index": this.index, source: line }, function(response) {
|
|
@@ -861,55 +922,64 @@
|
|
|
861
922
|
self.setInput(response.prefilled_input);
|
|
862
923
|
});
|
|
863
924
|
};
|
|
864
|
-
|
|
925
|
+
|
|
865
926
|
REPL.prototype.onEnterKey = function() {
|
|
866
927
|
var text = this.getInput();
|
|
867
928
|
if(text != "" && text !== undefined) {
|
|
868
|
-
|
|
929
|
+
var previousCommands = JSON.parse(localStorage.getItem("better_errors_previous_commands"));
|
|
930
|
+
this.previousCommandOffset = previousCommands.push(text);
|
|
931
|
+
if(previousCommands.length > 100) {
|
|
932
|
+
previousCommands.splice(0, 1);
|
|
933
|
+
this.previousCommandOffset -= 1;
|
|
934
|
+
}
|
|
935
|
+
localStorage.setItem("better_errors_previous_commands", JSON.stringify(previousCommands));
|
|
869
936
|
}
|
|
870
937
|
this.setInput("");
|
|
871
938
|
this.sendInput(text);
|
|
872
939
|
};
|
|
873
|
-
|
|
940
|
+
|
|
874
941
|
REPL.prototype.onNavigateHistory = function(direction) {
|
|
875
942
|
this.previousCommandOffset += direction;
|
|
876
|
-
|
|
943
|
+
var previousCommands = JSON.parse(localStorage.getItem("better_errors_previous_commands"));
|
|
944
|
+
|
|
877
945
|
if(this.previousCommandOffset < 0) {
|
|
878
946
|
this.previousCommandOffset = -1;
|
|
879
947
|
this.setInput("");
|
|
880
948
|
return;
|
|
881
949
|
}
|
|
882
|
-
|
|
883
|
-
if(this.previousCommandOffset >=
|
|
884
|
-
this.previousCommandOffset =
|
|
950
|
+
|
|
951
|
+
if(this.previousCommandOffset >= previousCommands.length) {
|
|
952
|
+
this.previousCommandOffset = previousCommands.length;
|
|
885
953
|
this.setInput("");
|
|
886
954
|
return;
|
|
887
955
|
}
|
|
888
|
-
|
|
889
|
-
this.setInput(
|
|
956
|
+
|
|
957
|
+
this.setInput(previousCommands[this.previousCommandOffset]);
|
|
890
958
|
};
|
|
891
|
-
|
|
959
|
+
|
|
892
960
|
REPL.prototype.onKeyDown = function(ev) {
|
|
893
961
|
if(ev.keyCode == 13) {
|
|
894
962
|
this.onEnterKey();
|
|
895
|
-
} else if(ev.keyCode == 38) {
|
|
896
|
-
// the user pressed the up arrow
|
|
963
|
+
} else if(ev.keyCode == 38 || (ev.ctrlKey && ev.keyCode == 80)) {
|
|
964
|
+
// the user pressed the up arrow or Ctrl-P
|
|
897
965
|
this.onNavigateHistory(-1);
|
|
966
|
+
ev.preventDefault();
|
|
898
967
|
return false;
|
|
899
|
-
} else if(ev.keyCode == 40) {
|
|
900
|
-
// the user pressed the down arrow
|
|
968
|
+
} else if(ev.keyCode == 40 || (ev.ctrlKey && ev.keyCode == 78)) {
|
|
969
|
+
// the user pressed the down arrow or Ctrl-N
|
|
901
970
|
this.onNavigateHistory(1);
|
|
971
|
+
ev.preventDefault();
|
|
902
972
|
return false;
|
|
903
973
|
}
|
|
904
974
|
};
|
|
905
|
-
|
|
975
|
+
|
|
906
976
|
function switchTo(el) {
|
|
907
977
|
if(previousFrameInfo) previousFrameInfo.style.display = "none";
|
|
908
978
|
previousFrameInfo = el;
|
|
909
979
|
|
|
910
980
|
el.style.display = "block";
|
|
911
981
|
|
|
912
|
-
var replInput = el.querySelector('.console input');
|
|
982
|
+
var replInput = el.querySelector('.be-console input');
|
|
913
983
|
if (replInput) replInput.focus();
|
|
914
984
|
}
|
|
915
985
|
|
|
@@ -923,21 +993,24 @@
|
|
|
923
993
|
apiCall("variables", { "index": index }, function(response) {
|
|
924
994
|
el.loaded = true;
|
|
925
995
|
if(response.error) {
|
|
926
|
-
el.innerHTML = "<
|
|
996
|
+
el.innerHTML = "<h2 class='error'>" + escapeHTML(response.error) + "</h2>";
|
|
997
|
+
if(response.explanation) {
|
|
998
|
+
el.innerHTML += "<p class='explanation'>" + escapeHTML(response.explanation) + "</p>";
|
|
999
|
+
}
|
|
1000
|
+
el.innerHTML += "<p><a target='_new' href='https://github.com/BetterErrors/better_errors'>More about Better Errors</a></p>";
|
|
927
1001
|
} else {
|
|
928
1002
|
el.innerHTML = response.html;
|
|
929
1003
|
|
|
930
|
-
var repl = el.querySelector(".repl .console");
|
|
1004
|
+
var repl = el.querySelector(".be-repl .be-console");
|
|
931
1005
|
if(repl) {
|
|
932
1006
|
new REPL(index).install(repl);
|
|
933
1007
|
}
|
|
934
|
-
|
|
935
|
-
switchTo(el);
|
|
936
1008
|
}
|
|
1009
|
+
switchTo(el);
|
|
937
1010
|
});
|
|
938
1011
|
}
|
|
939
1012
|
}
|
|
940
|
-
|
|
1013
|
+
|
|
941
1014
|
for(var i = 0; i < allFrames.length; i++) {
|
|
942
1015
|
(function(i, el) {
|
|
943
1016
|
var el = allFrames[i];
|
|
@@ -947,12 +1020,12 @@
|
|
|
947
1020
|
}
|
|
948
1021
|
el.className = "selected";
|
|
949
1022
|
previousFrame = el;
|
|
950
|
-
|
|
1023
|
+
|
|
951
1024
|
selectFrameInfo(el.attributes["data-index"].value);
|
|
952
1025
|
};
|
|
953
1026
|
})(i);
|
|
954
1027
|
}
|
|
955
|
-
|
|
1028
|
+
|
|
956
1029
|
// Click the first application frame
|
|
957
1030
|
(
|
|
958
1031
|
document.querySelector(".frames li.application") ||
|
|
@@ -968,7 +1041,7 @@
|
|
|
968
1041
|
var applicationFramesButtonIsInstalled = false;
|
|
969
1042
|
var applicationFramesButton = document.getElementById("application_frames");
|
|
970
1043
|
var allFramesButton = document.getElementById("all_frames");
|
|
971
|
-
|
|
1044
|
+
|
|
972
1045
|
// The application frames button only needs to be bound if
|
|
973
1046
|
// there are actually any application frames to look at.
|
|
974
1047
|
var installApplicationFramesButton = function() {
|
|
@@ -984,10 +1057,10 @@
|
|
|
984
1057
|
}
|
|
985
1058
|
return false;
|
|
986
1059
|
};
|
|
987
|
-
|
|
1060
|
+
|
|
988
1061
|
applicationFramesButtonIsInstalled = true;
|
|
989
1062
|
}
|
|
990
|
-
|
|
1063
|
+
|
|
991
1064
|
allFramesButton.onclick = function() {
|
|
992
1065
|
if(applicationFramesButtonIsInstalled) {
|
|
993
1066
|
applicationFramesButton.className = "";
|
|
@@ -999,7 +1072,7 @@
|
|
|
999
1072
|
}
|
|
1000
1073
|
return false;
|
|
1001
1074
|
};
|
|
1002
|
-
|
|
1075
|
+
|
|
1003
1076
|
// If there are no application frames, select the 'All Frames'
|
|
1004
1077
|
// tab by default.
|
|
1005
1078
|
if(applicationFramesCount > 0) {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
<%== text_heading("=", "%s at %s" % [
|
|
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,24 +1,31 @@
|
|
|
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 %>
|
|
8
15
|
</div>
|
|
9
16
|
|
|
10
17
|
<% if BetterErrors.binding_of_caller_available? && @frame.frame_binding %>
|
|
11
|
-
<div class="repl">
|
|
12
|
-
<div class="console">
|
|
18
|
+
<div class="be-repl">
|
|
19
|
+
<div class="be-console">
|
|
13
20
|
<pre></pre>
|
|
14
|
-
<div class="
|
|
21
|
+
<div class="command-line"><span class='prompt'>>></span> <input tabindex="1"/></div>
|
|
15
22
|
</div>
|
|
16
23
|
</div>
|
|
17
24
|
<% end %>
|
|
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
|
|
|
@@ -45,26 +52,28 @@
|
|
|
45
52
|
</div>
|
|
46
53
|
</div>
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
<% if BetterErrors.binding_of_caller_available? && @frame.frame_binding %>
|
|
56
|
+
<div class="sub">
|
|
57
|
+
<h3>Local Variables</h3>
|
|
58
|
+
<div class='inset variables'>
|
|
59
|
+
<table class="var_table">
|
|
60
|
+
<% @frame.local_variables.each do |name, value| %>
|
|
61
|
+
<tr><td class="name"><%= name %></td><td><pre><%== inspect_value value %></pre></td></tr>
|
|
62
|
+
<% end %>
|
|
63
|
+
</table>
|
|
64
|
+
</div>
|
|
56
65
|
</div>
|
|
57
|
-
</div>
|
|
58
66
|
|
|
59
|
-
<div class="sub">
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
<div class="sub">
|
|
68
|
+
<h3>Instance Variables</h3>
|
|
69
|
+
<div class="inset variables">
|
|
70
|
+
<table class="var_table">
|
|
71
|
+
<% @frame.instance_variables.each do |name, value| %>
|
|
72
|
+
<tr><td class="name"><%= name %></td><td><pre><%== inspect_value value %></pre></td></tr>
|
|
73
|
+
<% end %>
|
|
74
|
+
</table>
|
|
75
|
+
</div>
|
|
67
76
|
</div>
|
|
68
|
-
</div>
|
|
69
77
|
|
|
70
|
-
<!-- <%= Time.now.to_f - @var_start_time %> seconds -->
|
|
78
|
+
<!-- <%= Time.now.to_f - @var_start_time %> seconds -->
|
|
79
|
+
<% end %>
|