better_errors 1.0.1 → 1.1.0

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.

Potentially problematic release.


This version of better_errors might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 29ae99a691ade2e90114703be9bc09dfccf220b4
4
- data.tar.gz: 07dc30996fea81069a374862faf29989c843a06e
3
+ metadata.gz: fe0694430a61558b1ad22a156922e9a162b02352
4
+ data.tar.gz: 6804d151297037d1eb778143d3eb807fe7573e9d
5
5
  SHA512:
6
- metadata.gz: 9aa2006d43787d6931c28baddd137fbeebeae07efac5aab3b9ed052e8c3ab3d610b15c196f7a69c109606c423f6b9e25b84b7975aeb2baec5fb0c484208f2723
7
- data.tar.gz: f17296d9da8e87080839aabd3a1e113b6768885c3e2a4ed48dd3d73734d33c9c31b242fbfe0bfd475b350d1f99cccc2cd0efea08d9ee621db64b5f557c8645ea
6
+ metadata.gz: 3d0c58b00e4b6965e8dfd3ae3ded8a9efbfde40f8878854cf3ed86b46a5b344e647a73e24f541de858ea1f9f1b6b6c5b29145896b73870ac3eb34219edafb9db
7
+ data.tar.gz: 5fc01d0bd170e712c28d0efde81fa177eff86b6b36862bef1217749e1b39778c6e97e1899bed429f66dfaecfee45de843328935fe746402508892657232cf7aa
@@ -0,0 +1,3 @@
1
+ # Changelog
2
+
3
+ See https://github.com/charliesome/better_errors/releases
@@ -87,7 +87,7 @@ module BetterErrors
87
87
  end
88
88
 
89
89
  def real_exception(exception)
90
- if exception.respond_to? :original_exception
90
+ if exception.respond_to?(:original_exception) && exception.original_exception.is_a?(Exception)
91
91
  exception.original_exception
92
92
  else
93
93
  exception
@@ -48,23 +48,24 @@ module BetterErrors
48
48
  def self.has_binding_stack?(exception)
49
49
  exception.respond_to?(:__better_errors_bindings_stack) && exception.__better_errors_bindings_stack.any?
50
50
  end
51
-
51
+
52
52
  attr_reader :filename, :line, :name, :frame_binding
53
-
53
+
54
54
  def initialize(filename, line, name, frame_binding = nil)
55
55
  @filename = filename
56
56
  @line = line
57
57
  @name = name
58
58
  @frame_binding = frame_binding
59
-
59
+
60
60
  set_pretty_method_name if frame_binding
61
61
  end
62
-
62
+
63
63
  def application?
64
- root = BetterErrors.application_root
65
- filename.index(root) == 0 if root
64
+ if root = BetterErrors.application_root
65
+ filename.index(root) == 0 && filename.index("#{root}/vendor") != 0
66
+ end
66
67
  end
67
-
68
+
68
69
  def application_path
69
70
  filename[(BetterErrors.application_root.length+1)..-1]
70
71
  end
@@ -72,7 +73,7 @@ module BetterErrors
72
73
  def gem?
73
74
  Gem.path.any? { |path| filename.index(path) == 0 }
74
75
  end
75
-
76
+
76
77
  def gem_path
77
78
  if path = Gem.path.detect { |path| filename.index(path) == 0 }
78
79
  gem_name_and_version, path = filename.sub("#{path}/gems/", "").split("/", 2)
@@ -88,7 +89,7 @@ module BetterErrors
88
89
  def method_name
89
90
  @method_name || @name
90
91
  end
91
-
92
+
92
93
  def context
93
94
  if gem?
94
95
  :gem
@@ -98,7 +99,7 @@ module BetterErrors
98
99
  :dunno
99
100
  end
100
101
  end
101
-
102
+
102
103
  def pretty_path
103
104
  case context
104
105
  when :application; application_path
@@ -106,7 +107,7 @@ module BetterErrors
106
107
  else filename
107
108
  end
108
109
  end
109
-
110
+
110
111
  def local_variables
111
112
  return {} unless frame_binding
112
113
  frame_binding.eval("local_variables").each_with_object({}) do |name, hash|
@@ -122,7 +123,7 @@ module BetterErrors
122
123
  end
123
124
  end
124
125
  end
125
-
126
+
126
127
  def instance_variables
127
128
  return {} unless frame_binding
128
129
  Hash[visible_instance_variables.map { |x|
@@ -137,7 +138,7 @@ module BetterErrors
137
138
  def to_s
138
139
  "#{pretty_path}:#{line}:in `#{name}'"
139
140
  end
140
-
141
+
141
142
  private
142
143
  def set_pretty_method_name
143
144
  return if RUBY_VERSION < "2.0.0"
@@ -180,6 +180,7 @@
180
180
  padding-right: 20px;
181
181
  overflow-y: auto;
182
182
  word-wrap: break-word;
183
+ white-space: pre-wrap;
183
184
  height: auto;
184
185
  max-height: 7em;
185
186
  }
@@ -443,13 +444,13 @@
443
444
  font-weight: bold;
444
445
  font-size: 10pt;
445
446
  }
446
-
447
+
447
448
  .trace_info .title .location a {
448
449
  color:inherit;
449
450
  text-decoration:none;
450
451
  border-bottom:1px solid #aaaaaa;
451
452
  }
452
-
453
+
453
454
  .trace_info .title .location a:hover {
454
455
  border-color:#666666;
455
456
  }
@@ -472,7 +473,7 @@
472
473
  padding-bottom:9px;
473
474
  float:left;
474
475
  }
475
-
476
+
476
477
  .code_linenums span{
477
478
  display:block;
478
479
  padding:0 12px;
@@ -768,7 +769,7 @@
768
769
  (function() {
769
770
 
770
771
  var OID = <%== object_id.to_s.inspect %>;
771
-
772
+
772
773
  var previousFrame = null;
773
774
  var previousFrameInfo = null;
774
775
  var allFrames = document.querySelectorAll("ul.frames li");
@@ -786,68 +787,73 @@
786
787
  }
787
788
  };
788
789
  }
789
-
790
+
790
791
  function escapeHTML(html) {
791
792
  return html.replace(/&/, "&amp;").replace(/</g, "&lt;");
792
793
  }
793
-
794
+
794
795
  function REPL(index) {
795
796
  this.index = index;
796
-
797
- this.previousCommands = [];
798
- this.previousCommandOffset = 0;
797
+
798
+ var previousCommands = JSON.parse(localStorage.getItem("better_errors_previous_commands"));
799
+ if(previousCommands === null) {
800
+ localStorage.setItem("better_errors_previous_commands", JSON.stringify([]));
801
+ previousCommands = [];
802
+ }
803
+
804
+ this.previousCommandOffset = previousCommands.length;
799
805
  }
800
-
806
+
801
807
  REPL.all = [];
802
-
808
+
803
809
  REPL.prototype.install = function(containerElement) {
804
810
  this.container = containerElement;
805
-
811
+
806
812
  this.promptElement = this.container.querySelector(".prompt span");
807
813
  this.inputElement = this.container.querySelector("input");
808
814
  this.outputElement = this.container.querySelector("pre");
809
-
815
+
810
816
  var self = this;
811
817
  this.inputElement.onkeydown = function(ev) {
812
818
  self.onKeyDown(ev);
813
819
  };
814
-
820
+
815
821
  this.setPrompt(">>");
816
-
822
+
817
823
  REPL.all[this.index] = this;
818
824
  }
819
-
825
+
820
826
  REPL.prototype.focus = function() {
821
827
  this.inputElement.focus();
822
828
  };
823
-
829
+
824
830
  REPL.prototype.setPrompt = function(prompt) {
825
831
  this._prompt = prompt;
826
832
  this.promptElement.innerHTML = escapeHTML(prompt);
827
833
  };
828
-
834
+
829
835
  REPL.prototype.getInput = function() {
830
836
  return this.inputElement.value;
831
837
  };
832
-
838
+
833
839
  REPL.prototype.setInput = function(text) {
834
840
  this.inputElement.value = text;
835
-
841
+
836
842
  if(this.inputElement.setSelectionRange) {
837
843
  // set cursor to end of input
838
844
  this.inputElement.setSelectionRange(text.length, text.length);
839
845
  }
840
846
  };
841
-
847
+
842
848
  REPL.prototype.writeRawOutput = function(output) {
843
849
  this.outputElement.innerHTML += output;
844
850
  this.outputElement.scrollTop = this.outputElement.scrollHeight;
845
851
  };
846
-
852
+
847
853
  REPL.prototype.writeOutput = function(output) {
848
854
  this.writeRawOutput(escapeHTML(output));
849
855
  };
850
-
856
+
851
857
  REPL.prototype.sendInput = function(line) {
852
858
  var self = this;
853
859
  apiCall("eval", { "index": this.index, source: line }, function(response) {
@@ -861,48 +867,56 @@
861
867
  self.setInput(response.prefilled_input);
862
868
  });
863
869
  };
864
-
870
+
865
871
  REPL.prototype.onEnterKey = function() {
866
872
  var text = this.getInput();
867
873
  if(text != "" && text !== undefined) {
868
- this.previousCommandOffset = this.previousCommands.push(text);
874
+ var previousCommands = JSON.parse(localStorage.getItem("better_errors_previous_commands"));
875
+ this.previousCommandOffset = previousCommands.push(text);
876
+ if(previousCommands.length > 100) {
877
+ previousCommands.splice(0, 1);
878
+ }
879
+ localStorage.setItem("better_errors_previous_commands", JSON.stringify(previousCommands));
869
880
  }
870
881
  this.setInput("");
871
882
  this.sendInput(text);
872
883
  };
873
-
884
+
874
885
  REPL.prototype.onNavigateHistory = function(direction) {
875
886
  this.previousCommandOffset += direction;
876
-
887
+ var previousCommands = JSON.parse(localStorage.getItem("better_errors_previous_commands"));
888
+
877
889
  if(this.previousCommandOffset < 0) {
878
890
  this.previousCommandOffset = -1;
879
891
  this.setInput("");
880
892
  return;
881
893
  }
882
-
883
- if(this.previousCommandOffset >= this.previousCommands.length) {
884
- this.previousCommandOffset = this.previousCommands.length;
894
+
895
+ if(this.previousCommandOffset >= previousCommands.length) {
896
+ this.previousCommandOffset = previousCommands.length;
885
897
  this.setInput("");
886
898
  return;
887
899
  }
888
-
889
- this.setInput(this.previousCommands[this.previousCommandOffset]);
900
+
901
+ this.setInput(previousCommands[this.previousCommandOffset]);
890
902
  };
891
-
903
+
892
904
  REPL.prototype.onKeyDown = function(ev) {
893
905
  if(ev.keyCode == 13) {
894
906
  this.onEnterKey();
895
- } else if(ev.keyCode == 38) {
896
- // the user pressed the up arrow.
907
+ } else if(ev.keyCode == 38 || (ev.ctrlKey && ev.keyCode == 80)) {
908
+ // the user pressed the up arrow or Ctrl-P
897
909
  this.onNavigateHistory(-1);
910
+ ev.preventDefault();
898
911
  return false;
899
- } else if(ev.keyCode == 40) {
900
- // the user pressed the down arrow.
912
+ } else if(ev.keyCode == 40 || (ev.ctrlKey && ev.keyCode == 78)) {
913
+ // the user pressed the down arrow or Ctrl-N
901
914
  this.onNavigateHistory(1);
915
+ ev.preventDefault();
902
916
  return false;
903
917
  }
904
918
  };
905
-
919
+
906
920
  function switchTo(el) {
907
921
  if(previousFrameInfo) previousFrameInfo.style.display = "none";
908
922
  previousFrameInfo = el;
@@ -937,7 +951,7 @@
937
951
  });
938
952
  }
939
953
  }
940
-
954
+
941
955
  for(var i = 0; i < allFrames.length; i++) {
942
956
  (function(i, el) {
943
957
  var el = allFrames[i];
@@ -947,12 +961,12 @@
947
961
  }
948
962
  el.className = "selected";
949
963
  previousFrame = el;
950
-
964
+
951
965
  selectFrameInfo(el.attributes["data-index"].value);
952
966
  };
953
967
  })(i);
954
968
  }
955
-
969
+
956
970
  // Click the first application frame
957
971
  (
958
972
  document.querySelector(".frames li.application") ||
@@ -968,7 +982,7 @@
968
982
  var applicationFramesButtonIsInstalled = false;
969
983
  var applicationFramesButton = document.getElementById("application_frames");
970
984
  var allFramesButton = document.getElementById("all_frames");
971
-
985
+
972
986
  // The application frames button only needs to be bound if
973
987
  // there are actually any application frames to look at.
974
988
  var installApplicationFramesButton = function() {
@@ -984,10 +998,10 @@
984
998
  }
985
999
  return false;
986
1000
  };
987
-
1001
+
988
1002
  applicationFramesButtonIsInstalled = true;
989
1003
  }
990
-
1004
+
991
1005
  allFramesButton.onclick = function() {
992
1006
  if(applicationFramesButtonIsInstalled) {
993
1007
  applicationFramesButton.className = "";
@@ -999,7 +1013,7 @@
999
1013
  }
1000
1014
  return false;
1001
1015
  };
1002
-
1016
+
1003
1017
  // If there are no application frames, select the 'All Frames'
1004
1018
  // tab by default.
1005
1019
  if(applicationFramesCount > 0) {
@@ -1,3 +1,3 @@
1
1
  module BetterErrors
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -71,6 +71,40 @@ module BetterErrors
71
71
  status.should == 500
72
72
  end
73
73
 
74
+ context "original_exception" do
75
+ class OriginalExceptionException < Exception
76
+ attr_reader :original_exception
77
+
78
+ def initialize(message, original_exception = nil)
79
+ super(message)
80
+ @original_exception = original_exception
81
+ end
82
+ end
83
+
84
+ it "shows Original Exception if it responds_to and has an original_exception" do
85
+ app = Middleware.new(->env {
86
+ raise OriginalExceptionException.new("Other Exception", Exception.new("Original Exception"))
87
+ })
88
+
89
+ status, _, body = app.call({})
90
+
91
+ status.should == 500
92
+ body.join.should_not match(/Other Exception/)
93
+ body.join.should match(/Original Exception/)
94
+ end
95
+
96
+ it "won't crash if the exception responds_to but doesn't have an original_exception" do
97
+ app = Middleware.new(->env {
98
+ raise OriginalExceptionException.new("Other Exception")
99
+ })
100
+
101
+ status, _, body = app.call({})
102
+
103
+ status.should == 500
104
+ body.join.should match(/Other Exception/)
105
+ end
106
+ end
107
+
74
108
  it "returns ExceptionWrapper's status_code" do
75
109
  ad_ew = double("ActionDispatch::ExceptionWrapper")
76
110
  ad_ew.stub('new').with({}, exception ){ double("ExceptionWrapper", status_code: 404) }
@@ -25,7 +25,11 @@ module BetterErrors
25
25
  filled.should == " "
26
26
 
27
27
  output, prompt, filled = repl.send_input "end"
28
- output.should == "=> nil\n"
28
+ if RUBY_VERSION >= "2.1.0"
29
+ output.should == "=> :f\n"
30
+ else
31
+ output.should == "=> nil\n"
32
+ end
29
33
  prompt.should == ">>"
30
34
  filled.should == ""
31
35
  end
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: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charlie Somerville
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-08 00:00:00.000000000 Z
11
+ date: 2013-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erubis
@@ -50,6 +50,7 @@ files:
50
50
  - .gitignore
51
51
  - .travis.yml
52
52
  - .yardopts
53
+ - CHANGELOG.md
53
54
  - Gemfile
54
55
  - LICENSE.txt
55
56
  - README.md