better_errors 0.0.4 → 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.
Potentially problematic release.
This version of better_errors might be problematic. Click here for more details.
- data/README.md +9 -13
- data/lib/better_errors/error_page.rb +3 -1
- data/lib/better_errors/templates/main.erb +37 -25
- data/lib/better_errors/version.rb +1 -1
- metadata +1 -1
data/README.md
CHANGED
@@ -2,32 +2,28 @@
|
|
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
|
-

|
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
|
-
*
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
$ bundle
|
23
|
-
|
24
|
-
Or install it yourself as:
|
25
|
-
|
26
|
-
$ gem install better_errors
|
18
|
+
```ruby
|
19
|
+
gem "better_errors"
|
20
|
+
```
|
27
21
|
|
28
|
-
If you would like to use Better Errors' **advanced features**, you need to
|
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:
|
29
23
|
|
30
|
-
|
24
|
+
```ruby
|
25
|
+
gem "binding_of_caller"
|
26
|
+
```
|
31
27
|
|
32
28
|
This is an optional dependency however, and Better Errors will work without it.
|
33
29
|
|
@@ -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 =
|
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") }
|
@@ -243,15 +243,22 @@
|
|
243
243
|
<div class="location"><span class="filename"><%= frame.pretty_path %></span>, line <span class="line"><%= frame.line %></span></div>
|
244
244
|
<%== highlighted_code_block frame %>
|
245
245
|
|
246
|
-
|
247
|
-
<
|
248
|
-
|
249
|
-
<
|
250
|
-
|
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">>> <input/></div>
|
252
|
+
</div>
|
251
253
|
</div>
|
252
|
-
|
253
|
-
|
254
|
-
|
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 %>
|
255
262
|
</div>
|
256
263
|
<% end %>
|
257
264
|
<div style="clear:both"></div>
|
@@ -290,7 +297,7 @@
|
|
290
297
|
var el = document.getElementById("frame_info_" + index);
|
291
298
|
|
292
299
|
var varInfo = el.querySelector(".variable_info");
|
293
|
-
if(varInfo.innerHTML == "") {
|
300
|
+
if(varInfo && varInfo.innerHTML == "") {
|
294
301
|
apiCall("variables", { "index": index }, function(response) {
|
295
302
|
if(response.error) {
|
296
303
|
varInfo.innerHTML = "<span class='error'>" + escapeHTML(response.error) + "</span>";
|
@@ -306,7 +313,10 @@
|
|
306
313
|
previousFrameInfo = el;
|
307
314
|
previousFrameInfo.style.display = "block";
|
308
315
|
|
309
|
-
el.querySelector(".repl input")
|
316
|
+
var replInput = el.querySelector(".repl input");
|
317
|
+
if(replInput) {
|
318
|
+
replInput.focus();
|
319
|
+
}
|
310
320
|
}
|
311
321
|
|
312
322
|
for(var i = 0; i < frames.length; i++) {
|
@@ -322,21 +332,23 @@
|
|
322
332
|
};
|
323
333
|
var replPre = frameInfo.querySelector(".repl pre");
|
324
334
|
var replInput = frameInfo.querySelector(".repl input");
|
325
|
-
replInput
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
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
|
+
}
|
340
352
|
})(i, frames[i], frameInfos[i]);
|
341
353
|
}
|
342
354
|
|