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.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/.coveralls.yml +1 -0
  3. data/.github/workflows/ci.yml +130 -0
  4. data/.github/workflows/release.yml +64 -0
  5. data/.gitignore +10 -5
  6. data/.ruby-version +1 -0
  7. data/CHANGELOG.md +3 -0
  8. data/Gemfile +7 -7
  9. data/LICENSE.txt +1 -1
  10. data/README.md +103 -33
  11. data/better_errors.gemspec +26 -8
  12. data/gemfiles/pry010.gemfile +10 -0
  13. data/gemfiles/pry011.gemfile +9 -0
  14. data/gemfiles/pry09.gemfile +9 -0
  15. data/gemfiles/rack.gemfile +8 -0
  16. data/gemfiles/rack_boc.gemfile +9 -0
  17. data/gemfiles/rails42.gemfile +10 -0
  18. data/gemfiles/rails42_boc.gemfile +11 -0
  19. data/gemfiles/rails42_haml.gemfile +11 -0
  20. data/gemfiles/rails50.gemfile +9 -0
  21. data/gemfiles/rails50_boc.gemfile +10 -0
  22. data/gemfiles/rails50_haml.gemfile +10 -0
  23. data/gemfiles/rails51.gemfile +9 -0
  24. data/gemfiles/rails51_boc.gemfile +10 -0
  25. data/gemfiles/rails51_haml.gemfile +10 -0
  26. data/gemfiles/rails52.gemfile +9 -0
  27. data/gemfiles/rails52_boc.gemfile +10 -0
  28. data/gemfiles/rails52_haml.gemfile +10 -0
  29. data/gemfiles/rails60.gemfile +8 -0
  30. data/gemfiles/rails60_boc.gemfile +9 -0
  31. data/gemfiles/rails60_haml.gemfile +9 -0
  32. data/lib/better_errors/code_formatter/html.rb +1 -1
  33. data/lib/better_errors/code_formatter.rb +7 -7
  34. data/lib/better_errors/editor.rb +99 -0
  35. data/lib/better_errors/error_page.rb +83 -49
  36. data/lib/better_errors/exception_extension.rb +17 -0
  37. data/lib/better_errors/exception_hint.rb +29 -0
  38. data/lib/better_errors/inspectable_value.rb +45 -0
  39. data/lib/better_errors/middleware.rb +101 -21
  40. data/lib/better_errors/raised_exception.rb +89 -0
  41. data/lib/better_errors/repl/basic.rb +3 -3
  42. data/lib/better_errors/repl/pry.rb +20 -10
  43. data/lib/better_errors/repl.rb +6 -4
  44. data/lib/better_errors/stack_frame.rb +48 -71
  45. data/lib/better_errors/templates/main.erb +167 -94
  46. data/lib/better_errors/templates/text.erb +6 -3
  47. data/lib/better_errors/templates/variable_info.erb +33 -24
  48. data/lib/better_errors/version.rb +1 -1
  49. data/lib/better_errors.rb +35 -37
  50. metadata +150 -46
  51. data/.travis.yml +0 -6
  52. data/Rakefile +0 -4
  53. data/ext/mkrf_conf.rb +0 -11
  54. data/lib/better_errors/core_ext/exception.rb +0 -21
  55. data/spec/better_errors/code_formatter_spec.rb +0 -92
  56. data/spec/better_errors/error_page_spec.rb +0 -76
  57. data/spec/better_errors/middleware_spec.rb +0 -112
  58. data/spec/better_errors/repl/basic_spec.rb +0 -18
  59. data/spec/better_errors/repl/pry_spec.rb +0 -36
  60. data/spec/better_errors/repl/shared_examples.rb +0 -18
  61. data/spec/better_errors/stack_frame_spec.rb +0 -161
  62. data/spec/better_errors/support/my_source.rb +0 -20
  63. data/spec/better_errors_spec.rb +0 -73
  64. data/spec/spec_helper.rb +0 -7
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title><%= exception.class %> at <%= request_path %></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: 95px;
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: 115px;
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: 59px;
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.4em;
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: 20pt;
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: 7em;
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 .prompt span, textarea, .code_linenums {
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
- /* .prompt > span + input */
551
- .console .prompt {
559
+ /* .command-line > span + input */
560
+ .be-console .command-line {
552
561
  display: table;
553
562
  width: 100%;
554
563
  }
555
564
 
556
- .console .prompt span,
557
- .console .prompt input {
565
+ .be-console .command-line span,
566
+ .be-console .command-line input {
558
567
  display: table-cell;
559
568
  }
560
569
 
561
- .console .prompt span {
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 .prompt input {
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
- document.addEventListener("page:restore", function restoreCSS(e) {
723
- for(var i=0; i < document.styleSheets.length; i++) {
724
- document.styleSheets[i].disabled = false;
725
- }
726
- document.removeEventListener("page:restore", restoreCSS, false);
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><%= exception.class %></strong> <span>at <%= request_path %></span></h2>
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 = <%== object_id.to_s.inspect %>;
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("<", "&lt;").inspect %> + "/__better_errors/" + OID + "/" + method, true);
807
+ req.open("POST", "//" + window.location.host + <%== uri_prefix.gsub("<", "&lt;").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(/&/, "&amp;").replace(/</g, "&lt;");
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
- this.previousCommands = [];
798
- this.previousCommandOffset = 0;
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 span");
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
- this.previousCommandOffset = this.previousCommands.push(text);
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 >= this.previousCommands.length) {
884
- this.previousCommandOffset = this.previousCommands.length;
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(this.previousCommands[this.previousCommandOffset]);
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 = "<span class='error'>" + escapeHTML(response.error) + "</span>";
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" % [exception.class, request_path]) %>
1
+ <%== text_heading("=", "%s at %s" % [exception_type, request_path]) %>
2
2
 
3
- > <%== exception_message %>
4
- <% if backtrace_frames.any? %>
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"><span class="filename"><a href="<%= editor_url(@frame) %>"><%= @frame.pretty_path %></a></span></div>
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="prompt"><span>&gt;&gt;</span> <input/></div>
21
+ <div class="command-line"><span class='prompt'>&gt;&gt;</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
- <div class="sub">
49
- <h3>Local Variables</h3>
50
- <div class='inset variables'>
51
- <table class="var_table">
52
- <% @frame.local_variables.each do |name, value| %>
53
- <tr><td class="name"><%= name %></td><td><pre><%== inspect_value value %></pre></td></tr>
54
- <% end %>
55
- </table>
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
- <h3>Instance Variables</h3>
61
- <div class="inset variables">
62
- <table class="var_table">
63
- <% @frame.instance_variables.each do |name, value| %>
64
- <tr><td class="name"><%= name %></td><td><pre><%== inspect_value value %></pre></td></tr>
65
- <% end %>
66
- </table>
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 %>
@@ -1,3 +1,3 @@
1
1
  module BetterErrors
2
- VERSION = "1.0.0"
2
+ VERSION = "2.9.1"
3
3
  end