better_errors 2.0.0 → 2.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 +4 -4
- data/README.md +8 -3
- data/lib/better_errors.rb +1 -1
- data/lib/better_errors/code_formatter.rb +7 -7
- data/lib/better_errors/code_formatter/html.rb +1 -1
- data/lib/better_errors/error_page.rb +1 -1
- data/lib/better_errors/repl.rb +3 -3
- data/lib/better_errors/repl/basic.rb +2 -2
- data/lib/better_errors/repl/pry.rb +7 -7
- data/lib/better_errors/stack_frame.rb +1 -1
- data/lib/better_errors/templates/main.erb +2 -1
- data/lib/better_errors/version.rb +1 -1
- data/spec/better_errors/code_formatter_spec.rb +7 -7
- data/spec/better_errors/error_page_spec.rb +12 -12
- data/spec/better_errors/repl/basic_spec.rb +1 -1
- data/spec/better_errors/repl/shared_examples.rb +2 -2
- data/spec/better_errors/stack_frame_spec.rb +5 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f7d7bc114aeb551e440f8da17f54695d2e577c0
|
4
|
+
data.tar.gz: 98a63563c768d1dc39cfde6b480f08ef57a4d8ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39f582d75f4f5036509eba3c3c97b99f6ee7f695ff3c6913a860ad3d20fb6e22be3d79cc27daa9cb1328b597c83e40c08ffc608497f3213ac738fc56b11670f2
|
7
|
+
data.tar.gz: ba38267fddb50b97ff7fb9ddb27489d03526521d0a479859fe90c6095cc03f37d9f103110879650c76efe9ea1de1f9a1726aadf1ce4ed6e567b9b9317ecf963b
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# Better Errors [](https://rubygems.org/gems/better_errors) [](https://travis-ci.org/charliesome/better_errors) [](https://codeclimate.com/github/charliesome/better_errors)
|
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 in any Rack app as Rack middleware.
|
4
4
|
|
5
|
-

|
6
6
|
|
7
7
|
## Features
|
8
8
|
|
@@ -21,7 +21,7 @@ group :development do
|
|
21
21
|
end
|
22
22
|
```
|
23
23
|
|
24
|
-
If you would like to use Better Errors' **advanced features** (REPL, local/instance variable inspection, pretty stack frame names), you need to add the [`binding_of_caller`](https://github.com/banister/binding_of_caller) gem by [@banisterfiend](
|
24
|
+
If you would like to use Better Errors' **advanced features** (REPL, local/instance variable inspection, pretty stack frame names), you need to add the [`binding_of_caller`](https://github.com/banister/binding_of_caller) gem by [@banisterfiend](https://twitter.com/banisterfiend) to your Gemfile:
|
25
25
|
|
26
26
|
```ruby
|
27
27
|
gem "binding_of_caller"
|
@@ -77,6 +77,11 @@ get "/" do
|
|
77
77
|
end
|
78
78
|
```
|
79
79
|
|
80
|
+
### Plain text
|
81
|
+
|
82
|
+
Better Errors will render a plain text error page when the request is an
|
83
|
+
`XMLHttpRequest` or when the `Accept` header does *not* include 'html'.
|
84
|
+
|
80
85
|
### Unicorn, Puma, and other multi-worker servers
|
81
86
|
|
82
87
|
Better Errors works by leaving a lot of context in server process memory. If
|
data/lib/better_errors.rb
CHANGED
@@ -11,9 +11,9 @@ module BetterErrors
|
|
11
11
|
".erb" => :erb,
|
12
12
|
".haml" => :haml
|
13
13
|
}
|
14
|
-
|
14
|
+
|
15
15
|
attr_reader :filename, :line, :context
|
16
|
-
|
16
|
+
|
17
17
|
def initialize(filename, line, context = 5)
|
18
18
|
@filename = filename
|
19
19
|
@line = line
|
@@ -29,7 +29,7 @@ module BetterErrors
|
|
29
29
|
def formatted_code
|
30
30
|
formatted_lines.join
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def coderay_scanner
|
34
34
|
ext = File.extname(filename)
|
35
35
|
FILE_TYPES[ext] || :text
|
@@ -40,20 +40,20 @@ module BetterErrors
|
|
40
40
|
yield (current_line == line), current_line, str
|
41
41
|
}
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def highlighted_lines
|
45
45
|
CodeRay.scan(context_lines.join, coderay_scanner).div(wrap: nil).lines
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def context_lines
|
49
49
|
range = line_range
|
50
50
|
source_lines[(range.begin - 1)..(range.end - 1)] or raise Errno::EINVAL
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
def source_lines
|
54
54
|
@source_lines ||= File.readlines(filename)
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def line_range
|
58
58
|
min = [line - context, 1].max
|
59
59
|
max = [line + context, source_lines.count].min
|
@@ -103,7 +103,7 @@ module BetterErrors
|
|
103
103
|
CGI.escapeHTML(obj.inspect)
|
104
104
|
rescue NoMethodError
|
105
105
|
"<span class='unsupported'>(object doesn't support inspect)</span>"
|
106
|
-
rescue Exception
|
106
|
+
rescue Exception
|
107
107
|
"<span class='unsupported'>(exception was raised in inspect)</span>"
|
108
108
|
end
|
109
109
|
end
|
data/lib/better_errors/repl.rb
CHANGED
@@ -9,17 +9,17 @@ module BetterErrors
|
|
9
9
|
def self.provider
|
10
10
|
@provider ||= const_get detect[:const]
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def self.provider=(prov)
|
14
14
|
@provider = prov
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def self.detect
|
18
18
|
PROVIDERS.find { |prov|
|
19
19
|
test_provider prov
|
20
20
|
}
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def self.test_provider(provider)
|
24
24
|
require provider[:impl]
|
25
25
|
true
|
@@ -9,29 +9,29 @@ module BetterErrors
|
|
9
9
|
Fiber.yield
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
class Output
|
14
14
|
def initialize
|
15
15
|
@buffer = ""
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def puts(*args)
|
19
19
|
args.each do |arg|
|
20
20
|
@buffer << "#{arg.chomp}\n"
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def tty?
|
25
25
|
false
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def read_buffer
|
29
29
|
@buffer
|
30
30
|
ensure
|
31
31
|
@buffer = ""
|
32
32
|
end
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def initialize(binding)
|
36
36
|
@fiber = Fiber.new do
|
37
37
|
@pry.repl binding
|
@@ -42,7 +42,7 @@ module BetterErrors
|
|
42
42
|
@pry.hooks.clear_all if defined?(@pry.hooks.clear_all)
|
43
43
|
@fiber.resume
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
def send_input(str)
|
47
47
|
local ::Pry.config, color: false, pager: false do
|
48
48
|
@fiber.resume "#{str}\n"
|
@@ -59,7 +59,7 @@ module BetterErrors
|
|
59
59
|
rescue
|
60
60
|
[">>", ""]
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
private
|
64
64
|
def local(obj, attrs)
|
65
65
|
old_attrs = {}
|
@@ -33,7 +33,7 @@ module BetterErrors
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def gem_path
|
36
|
-
if path = Gem.path.detect { |
|
36
|
+
if path = Gem.path.detect { |p| filename.index(p) == 0 }
|
37
37
|
gem_name_and_version, path = filename.sub("#{path}/gems/", "").split("/", 2)
|
38
38
|
/(?<gem_name>.+)-(?<gem_version>[\w.]+)/ =~ gem_name_and_version
|
39
39
|
"#{gem_name} (#{gem_version}) #{path}"
|
@@ -182,7 +182,7 @@
|
|
182
182
|
word-wrap: break-word;
|
183
183
|
white-space: pre-wrap;
|
184
184
|
height: auto;
|
185
|
-
max-height:
|
185
|
+
max-height: 7.5em;
|
186
186
|
}
|
187
187
|
|
188
188
|
@media screen and (max-width: 1100px) {
|
@@ -875,6 +875,7 @@
|
|
875
875
|
this.previousCommandOffset = previousCommands.push(text);
|
876
876
|
if(previousCommands.length > 100) {
|
877
877
|
previousCommands.splice(0, 1);
|
878
|
+
this.previousCommandOffset -= 1;
|
878
879
|
}
|
879
880
|
localStorage.setItem("better_errors_previous_commands", JSON.stringify(previousCommands));
|
880
881
|
}
|
@@ -3,16 +3,16 @@ require "spec_helper"
|
|
3
3
|
module BetterErrors
|
4
4
|
describe CodeFormatter do
|
5
5
|
let(:filename) { File.expand_path("../support/my_source.rb", __FILE__) }
|
6
|
-
|
6
|
+
|
7
7
|
let(:formatter) { CodeFormatter.new(filename, 8) }
|
8
|
-
|
8
|
+
|
9
9
|
it "picks an appropriate scanner" do
|
10
10
|
formatter.coderay_scanner.should == :ruby
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
it "shows 5 lines of context" do
|
14
14
|
formatter.line_range.should == (3..13)
|
15
|
-
|
15
|
+
|
16
16
|
formatter.context_lines.should == [
|
17
17
|
"three\n",
|
18
18
|
"four\n",
|
@@ -43,12 +43,12 @@ module BetterErrors
|
|
43
43
|
formatter = CodeFormatter::HTML.new(filename, 20)
|
44
44
|
formatter.output.should_not == formatter.source_unavailable
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
it "doesn't barf when the lines don't make any sense" do
|
48
48
|
formatter = CodeFormatter::HTML.new(filename, 999)
|
49
49
|
formatter.output.should == formatter.source_unavailable
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
it "doesn't barf when the file doesn't exist" do
|
53
53
|
formatter = CodeFormatter::HTML.new("fkdguhskd7e l", 1)
|
54
54
|
formatter.output.should == formatter.source_unavailable
|
@@ -82,7 +82,7 @@ module BetterErrors
|
|
82
82
|
formatter = CodeFormatter::Text.new(filename, 999)
|
83
83
|
formatter.output.should == formatter.source_unavailable
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
it "doesn't barf when the file doesn't exist" do
|
87
87
|
formatter = CodeFormatter::Text.new("fkdguhskd7e l", 1)
|
88
88
|
formatter.output.should == formatter.source_unavailable
|
@@ -3,36 +3,36 @@ require "spec_helper"
|
|
3
3
|
module BetterErrors
|
4
4
|
describe ErrorPage do
|
5
5
|
let!(:exception) { raise ZeroDivisionError, "you divided by zero you silly goose!" rescue $! }
|
6
|
-
|
6
|
+
|
7
7
|
let(:error_page) { ErrorPage.new exception, { "PATH_INFO" => "/some/path" } }
|
8
|
-
|
8
|
+
|
9
9
|
let(:response) { error_page.render }
|
10
|
-
|
10
|
+
|
11
11
|
let(:empty_binding) {
|
12
12
|
local_a = :value_for_local_a
|
13
13
|
local_b = :value_for_local_b
|
14
|
-
|
14
|
+
|
15
15
|
@inst_c = :value_for_inst_c
|
16
16
|
@inst_d = :value_for_inst_d
|
17
|
-
|
17
|
+
|
18
18
|
binding
|
19
19
|
}
|
20
|
-
|
20
|
+
|
21
21
|
it "includes the error message" do
|
22
22
|
response.should include("you divided by zero you silly goose!")
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it "includes the request path" do
|
26
26
|
response.should include("/some/path")
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it "includes the exception class" do
|
30
30
|
response.should include("ZeroDivisionError")
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
context "variable inspection" do
|
34
34
|
let(:exception) { empty_binding.eval("raise") rescue $! }
|
35
|
-
|
35
|
+
|
36
36
|
if BetterErrors.binding_of_caller_available?
|
37
37
|
it "shows local variables" do
|
38
38
|
html = error_page.do_variables("index" => 0)[:html]
|
@@ -47,7 +47,7 @@ module BetterErrors
|
|
47
47
|
html.should include(%{gem "binding_of_caller"})
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
it "shows instance variables" do
|
52
52
|
html = error_page.do_variables("index" => 0)[:html]
|
53
53
|
html.should include("inst_c")
|
@@ -65,7 +65,7 @@ module BetterErrors
|
|
65
65
|
html.should_not include("<pre>:value_for_inst_d</pre>")
|
66
66
|
end
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
it "doesn't die if the source file is not a real filename" do
|
70
70
|
exception.stub(:backtrace).and_return([
|
71
71
|
"<internal:prelude>:10:in `spawn_rack_application'"
|
@@ -3,13 +3,13 @@ shared_examples_for "a REPL provider" do
|
|
3
3
|
repl.send_input("local_a = 456")
|
4
4
|
fresh_binding.eval("local_a").should == 456
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
it "returns a tuple of output and the new prompt" do
|
8
8
|
output, prompt = repl.send_input("1 + 2")
|
9
9
|
output.should == "=> 3\n"
|
10
10
|
prompt.should == ">>"
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
it "doesn't barf if the code throws an exception" do
|
14
14
|
output, prompt = repl.send_input("raise Exception")
|
15
15
|
output.should include "Exception: Exception"
|
@@ -7,20 +7,20 @@ module BetterErrors
|
|
7
7
|
BetterErrors.stub(:application_root).and_return("/abc/xyz")
|
8
8
|
frame = StackFrame.new("/abc/xyz/app/controllers/crap_controller.rb", 123, "index")
|
9
9
|
|
10
|
-
frame.
|
10
|
+
frame.should be_application
|
11
11
|
end
|
12
12
|
|
13
13
|
it "is false for everything else" do
|
14
14
|
BetterErrors.stub(:application_root).and_return("/abc/xyz")
|
15
15
|
frame = StackFrame.new("/abc/nope", 123, "foo")
|
16
16
|
|
17
|
-
frame.
|
17
|
+
frame.should_not be_application
|
18
18
|
end
|
19
19
|
|
20
20
|
it "doesn't care if no application_root is set" do
|
21
21
|
frame = StackFrame.new("/abc/xyz/app/controllers/crap_controller.rb", 123, "index")
|
22
22
|
|
23
|
-
frame.
|
23
|
+
frame.should_not be_application
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -29,14 +29,14 @@ module BetterErrors
|
|
29
29
|
Gem.stub(:path).and_return(["/abc/xyz"])
|
30
30
|
frame = StackFrame.new("/abc/xyz/gems/whatever-1.2.3/lib/whatever.rb", 123, "foo")
|
31
31
|
|
32
|
-
frame.
|
32
|
+
frame.should be_gem
|
33
33
|
end
|
34
34
|
|
35
35
|
it "is false for everything else" do
|
36
36
|
Gem.stub(:path).and_return(["/abc/xyz"])
|
37
37
|
frame = StackFrame.new("/abc/nope", 123, "foo")
|
38
38
|
|
39
|
-
frame.
|
39
|
+
frame.should_not be_gem
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
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: 2.
|
4
|
+
version: 2.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: 2014-
|
11
|
+
date: 2014-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: erubis
|