better_errors 0.0.3 → 0.0.5

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.
data/README.md CHANGED
@@ -2,28 +2,30 @@
2
2
 
3
3
  Better Errors replaces the standard Rails error page with a much better and more useful error page. It is also usable outside of Rails.
4
4
 
5
- ![image](http://i.imgur.com/quHUZ.png)
5
+ ![image](http://i.imgur.com/urVDW.png)
6
6
 
7
7
  ## Features
8
8
 
9
9
  * Full stack trace
10
10
  * Source code inspection for all stack frames (with highlighting)
11
11
  * Local and instance variable inspection
12
- * Ruby console on every stack frame
12
+ * Live REPL on every stack frame
13
13
 
14
14
  ## Installation
15
15
 
16
16
  Add this line to your application's Gemfile (under the **development** group):
17
17
 
18
- gem 'better_errors'
19
-
20
- And then execute:
18
+ ```ruby
19
+ gem "better_errors"
20
+ ```
21
21
 
22
- $ bundle
22
+ If you would like to use Better Errors' **advanced features**, you need to add the [`binding_of_caller`](https://github.com/banister/binding_of_caller) gem to your Gemfile:
23
23
 
24
- Or install it yourself as:
24
+ ```ruby
25
+ gem "binding_of_caller"
26
+ ```
25
27
 
26
- $ gem install better_errors
28
+ This is an optional dependency however, and Better Errors will work without it.
27
29
 
28
30
  ## Usage
29
31
 
@@ -30,8 +30,10 @@ module BetterErrors
30
30
 
31
31
  def do_eval(opts)
32
32
  index = opts["index"].to_i
33
+ binding = backtrace_frames[index].frame_binding
34
+ return { error: "binding_of_caller unavailable" } unless binding
33
35
  response = begin
34
- result = backtrace_frames[index].frame_binding.eval(opts["source"])
36
+ result = binding.eval(opts["source"])
35
37
  { result: result.inspect }
36
38
  rescue Exception => e
37
39
  { error: (e.inspect rescue e.class.name rescue "Exception") }
@@ -14,7 +14,7 @@
14
14
  }
15
15
  header {
16
16
  padding:32px 32px;
17
- border-bottom:1px solid #ea6756;
17
+ border-bottom:1px solid #e64c38;
18
18
  background-color: #ffe5e7;
19
19
  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffe5e7), to(#ffb2b8)); /* Safari 4+, Chrome */
20
20
  background-image: -webkit-linear-gradient(top, #ffe5e7, #ffb2b8); /* Chrome 10+, Safari 5.1+, iOS 5+ */
@@ -41,6 +41,40 @@
41
41
  header table th, header table td {
42
42
  padding:4px 6px;
43
43
  }
44
+ nav {
45
+ display:block;
46
+ padding:12px 12px;
47
+ border-bottom:1px solid #000000;
48
+ background-color: #444444;
49
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#444444), to(#222222)); /* Safari 4+, Chrome */
50
+ background-image: -webkit-linear-gradient(top, #444444, #222222); /* Chrome 10+, Safari 5.1+, iOS 5+ */
51
+ background-image: -moz-linear-gradient(top, #444444, #222222); /* Firefox 3.6-15 */
52
+ background-image: -o-linear-gradient(top, #444444, #222222); /* Opera 11.10-12.00 */
53
+ background-image: linear-gradient(to bottom, #444444, #222222); /* Firefox 16+, IE10, Opera 12.50+ */
54
+ }
55
+ nav a {
56
+ color:#ffffff;
57
+ text-decoration:none;
58
+ padding:4px 16px;
59
+ border-radius:16px;
60
+ }
61
+ nav a:hover {
62
+ background-color: #666666;
63
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#666666), to(#444444)); /* Safari 4+, Chrome */
64
+ background-image: -webkit-linear-gradient(top, #666666, #444444); /* Chrome 10+, Safari 5.1+, iOS 5+ */
65
+ background-image: -moz-linear-gradient(top, #666666, #444444); /* Firefox 3.6-15 */
66
+ background-image: -o-linear-gradient(top, #666666, #444444); /* Opera 11.10-12.00 */
67
+ background-image: linear-gradient(to bottom, #666666, #444444); /* Firefox 16+, IE10, Opera 12.50+ */
68
+ }
69
+ nav a.selected {
70
+ color:#000000;
71
+ background-color: #efefef;
72
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#cfcfcf)); /* Safari 4+, Chrome */
73
+ background-image: -webkit-linear-gradient(top, #efefef, #cfcfcf); /* Chrome 10+, Safari 5.1+, iOS 5+ */
74
+ background-image: -moz-linear-gradient(top, #efefef, #cfcfcf); /* Firefox 3.6-15 */
75
+ background-image: -o-linear-gradient(top, #efefef, #cfcfcf); /* Opera 11.10-12.00 */
76
+ background-image: linear-gradient(to bottom, #efefef, #cfcfcf); /* Firefox 16+, IE10, Opera 12.50+ */
77
+ }
44
78
  .frames {
45
79
  width:50%;
46
80
  float:left;
@@ -183,6 +217,10 @@
183
217
  <% end %>
184
218
  </table>
185
219
  </header>
220
+ <nav>
221
+ <a href="#" id="application_frames">Application Frames</a>
222
+ <a href="#" id="all_frames">All Frames</a>
223
+ </nav>
186
224
  <section class="backtrace">
187
225
  <ul class="frames">
188
226
  <% backtrace_frames.each_with_index do |frame, index| %>
@@ -205,15 +243,22 @@
205
243
  <div class="location"><span class="filename"><%= frame.pretty_path %></span>, line <span class="line"><%= frame.line %></span></div>
206
244
  <%== highlighted_code_block frame %>
207
245
 
208
- <div class="repl">
209
- <h3>REPL</h3>
210
- <div class="console">
211
- <pre></pre>
212
- <div class="prompt">&gt;&gt; <input/></div>
246
+ <% if BetterErrors.binding_of_caller_available? %>
247
+ <div class="repl">
248
+ <h3>REPL</h3>
249
+ <div class="console">
250
+ <pre></pre>
251
+ <div class="prompt">&gt;&gt; <input/></div>
252
+ </div>
213
253
  </div>
214
- </div>
215
-
216
- <div class="variable_info"></div>
254
+
255
+ <div class="variable_info"></div>
256
+ <% else %>
257
+ <h3>Advanced features unavailable</h3>
258
+ <p class="error">
259
+ You must add <code>gem "binding_of_caller"</code> to your Gemfile to enable the REPL and local/instance variable inspection.
260
+ </p>
261
+ <% end %>
217
262
  </div>
218
263
  <% end %>
219
264
  <div style="clear:both"></div>
@@ -252,7 +297,7 @@
252
297
  var el = document.getElementById("frame_info_" + index);
253
298
 
254
299
  var varInfo = el.querySelector(".variable_info");
255
- if(varInfo.innerHTML == "") {
300
+ if(varInfo && varInfo.innerHTML == "") {
256
301
  apiCall("variables", { "index": index }, function(response) {
257
302
  if(response.error) {
258
303
  varInfo.innerHTML = "<span class='error'>" + escapeHTML(response.error) + "</span>";
@@ -268,7 +313,10 @@
268
313
  previousFrameInfo = el;
269
314
  previousFrameInfo.style.display = "block";
270
315
 
271
- el.querySelector(".repl input").focus();
316
+ var replInput = el.querySelector(".repl input");
317
+ if(replInput) {
318
+ replInput.focus();
319
+ }
272
320
  }
273
321
 
274
322
  for(var i = 0; i < frames.length; i++) {
@@ -284,25 +332,54 @@
284
332
  };
285
333
  var replPre = frameInfo.querySelector(".repl pre");
286
334
  var replInput = frameInfo.querySelector(".repl input");
287
- replInput.onkeydown = function(ev) {
288
- if(ev.keyCode == 13) {
289
- var text = replInput.value;
290
- replInput.value = "";
291
- apiCall("eval", { "index": index, source: text }, function(response) {
292
- replPre.innerHTML += ">> " + response.highlighted_input + "\n";
293
- if(response.error) {
294
- replPre.innerHTML += "!! " + escapeHTML(response.error) + "\n";
295
- } else {
296
- replPre.innerHTML += "=> " + escapeHTML(response.result) + "\n";
297
- }
298
- replPre.scrollTop = replPre.offsetHeight;
299
- });
300
- }
301
- };
335
+ if(replInput) {
336
+ replInput.onkeydown = function(ev) {
337
+ if(ev.keyCode == 13) {
338
+ var text = replInput.value;
339
+ replInput.value = "";
340
+ apiCall("eval", { "index": index, source: text }, function(response) {
341
+ replPre.innerHTML += ">> " + response.highlighted_input + "\n";
342
+ if(response.error) {
343
+ replPre.innerHTML += "!! " + escapeHTML(response.error) + "\n";
344
+ } else {
345
+ replPre.innerHTML += "=> " + escapeHTML(response.result) + "\n";
346
+ }
347
+ replPre.scrollTop = replPre.offsetHeight;
348
+ });
349
+ }
350
+ };
351
+ }
302
352
  })(i, frames[i], frameInfos[i]);
303
353
  }
304
354
 
305
355
  document.querySelector(".frames li:first-child").click();
356
+
357
+ var applicationFrames = document.getElementById("application_frames");
358
+ var allFrames = document.getElementById("all_frames");
359
+
360
+ applicationFrames.onclick = function() {
361
+ allFrames.className = "";
362
+ applicationFrames.className = "selected";
363
+ for(var i = 0; i < frames.length; i++) {
364
+ if(frames[i].attributes["data-context"].value == "application") {
365
+ frames[i].style.display = "block";
366
+ } else {
367
+ frames[i].style.display = "none";
368
+ }
369
+ }
370
+ return false;
371
+ };
372
+
373
+ allFrames.onclick = function() {
374
+ applicationFrames.className = "";
375
+ allFrames.className = "selected";
376
+ for(var i = 0; i < frames.length; i++) {
377
+ frames[i].style.display = "block";
378
+ }
379
+ return false;
380
+ };
381
+
382
+ applicationFrames.click();
306
383
  })();
307
384
  </script>
308
385
  </html>
@@ -1,3 +1,3 @@
1
1
  module BetterErrors
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.5"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_errors
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: