better_errors 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
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
|
-
![image](http://i.imgur.com/
|
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
|
-
*
|
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
|
|