better_errors-creditkudos 2.1.1

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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +8 -0
  4. data/.yardopts +1 -0
  5. data/CHANGELOG.md +3 -0
  6. data/Gemfile +11 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +128 -0
  9. data/Rakefile +13 -0
  10. data/better_errors-creditkudos.gemspec +28 -0
  11. data/lib/better_errors.rb +152 -0
  12. data/lib/better_errors/code_formatter.rb +63 -0
  13. data/lib/better_errors/code_formatter/html.rb +26 -0
  14. data/lib/better_errors/code_formatter/text.rb +14 -0
  15. data/lib/better_errors/error_page.rb +129 -0
  16. data/lib/better_errors/exception_extension.rb +17 -0
  17. data/lib/better_errors/middleware.rb +141 -0
  18. data/lib/better_errors/rails.rb +28 -0
  19. data/lib/better_errors/raised_exception.rb +68 -0
  20. data/lib/better_errors/repl.rb +30 -0
  21. data/lib/better_errors/repl/basic.rb +20 -0
  22. data/lib/better_errors/repl/pry.rb +78 -0
  23. data/lib/better_errors/stack_frame.rb +111 -0
  24. data/lib/better_errors/templates/main.erb +1032 -0
  25. data/lib/better_errors/templates/text.erb +21 -0
  26. data/lib/better_errors/templates/variable_info.erb +72 -0
  27. data/lib/better_errors/version.rb +3 -0
  28. data/spec/better_errors/code_formatter_spec.rb +92 -0
  29. data/spec/better_errors/error_page_spec.rb +122 -0
  30. data/spec/better_errors/middleware_spec.rb +180 -0
  31. data/spec/better_errors/raised_exception_spec.rb +72 -0
  32. data/spec/better_errors/repl/basic_spec.rb +18 -0
  33. data/spec/better_errors/repl/pry_spec.rb +40 -0
  34. data/spec/better_errors/repl/shared_examples.rb +18 -0
  35. data/spec/better_errors/stack_frame_spec.rb +157 -0
  36. data/spec/better_errors/support/my_source.rb +20 -0
  37. data/spec/better_errors_spec.rb +73 -0
  38. data/spec/spec_helper.rb +5 -0
  39. data/spec/without_binding_of_caller.rb +9 -0
  40. metadata +136 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f2a6d2b9e47dea68238e091ce6321912938bfd39
4
+ data.tar.gz: ba2cbaed992e4cd2f24ac099c1bfad1b3ac81926
5
+ SHA512:
6
+ metadata.gz: 1e814e90c2024718b0369fa1e703d90f0d623fd0a6926388c0a5b98b220a2c67880ec3254a966b951dbdf0109bdc76f6de82ec2cdfc2af5d4fd45e8567827362
7
+ data.tar.gz: 2da774b33b1310bc8754072fa5cc61705eae2ab1f5cf1e9f695f99cda6355264added72b5935a8be76df9de6d35cb8cbcd4195e0b545e83b08af13a3fa971cd1
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ /tmp
3
+ /Gemfile.lock
4
+ /coverage
5
+ /.yardoc
6
+ /doc
7
+ /.bundle
8
+ /vendor/gems
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ sudo: false
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.0
6
+ - 2.1
7
+ - 2.2
8
+ - 2.3.1
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown --no-private
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # Changelog
2
+
3
+ See https://github.com/charliesome/better_errors/releases
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem "rake"
6
+ gem "rack", "1.6.4"
7
+ gem "rspec", "2.14.1"
8
+ gem "binding_of_caller", platforms: :ruby
9
+ gem "pry", "0.9.12"
10
+ gem "yard"
11
+ gem "kramdown"
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012-2016 Charlie Somerville
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # Better Errors [![Gem Version](https://img.shields.io/gem/v/better_errors.svg)](https://rubygems.org/gems/better_errors) [![Build Status](https://travis-ci.org/charliesome/better_errors.svg)](https://travis-ci.org/charliesome/better_errors) [![Code Climate](https://img.shields.io/codeclimate/github/charliesome/better_errors.svg)](https://codeclimate.com/github/charliesome/better_errors)
2
+
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
+
5
+ ![image](https://i.imgur.com/6zBGAAb.png)
6
+
7
+ ## Features
8
+
9
+ * Full stack trace
10
+ * Source code inspection for all stack frames (with highlighting)
11
+ * Local and instance variable inspection
12
+ * Live REPL on every stack frame
13
+
14
+ ## Installation
15
+
16
+ Add this to your Gemfile:
17
+
18
+ ```ruby
19
+ group :development do
20
+ gem "better_errors"
21
+ end
22
+ ```
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](https://twitter.com/banisterfiend) to your Gemfile:
25
+
26
+ ```ruby
27
+ gem "binding_of_caller"
28
+ ```
29
+
30
+ This is an optional dependency however, and Better Errors will work without it.
31
+
32
+ _Note: If you discover that Better Errors isn't working - particularly after upgrading from version 0.5.0 or less - be sure to set `config.consider_all_requests_local = true` in `config/environments/development.rb`._
33
+
34
+ ## Security
35
+
36
+ **NOTE:** It is *critical* you put better\_errors in the **development** section. **Do NOT run better_errors in production, or on Internet facing hosts.**
37
+
38
+ You will notice that the only machine that gets the Better Errors page is localhost, which means you get the default error page if you are developing on a remote host (or a virtually remote host, such as a Vagrant box). Obviously, the REPL is not something you want to expose to the public, but there may also be other pieces of sensitive information available in the backtrace.
39
+
40
+ To poke selective holes in this security mechanism, you can add a line like this to your startup (for example, on Rails it would be `config/environments/development.rb`)
41
+
42
+ ```ruby
43
+ BetterErrors::Middleware.allow_ip! ENV['TRUSTED_IP'] if ENV['TRUSTED_IP']
44
+ ```
45
+
46
+ Then run Rails like this:
47
+
48
+ ```shell
49
+ TRUSTED_IP=66.68.96.220 rails s
50
+ ```
51
+
52
+ Note that the `allow_ip!` is actually backed by a `Set`, so you can add more than one IP address or subnet.
53
+
54
+ **Tip:** You can find your apparent IP by hitting the old error page's "Show env dump" and looking at "REMOTE_ADDR".
55
+
56
+ **VirtualBox:** If you are using VirtualBox and are accessing the guest from your host's browser, you will need to use `allow_ip!` to see the error page.
57
+
58
+ ## Usage
59
+
60
+ If you're using Rails, there's nothing else you need to do.
61
+
62
+ If you're not using Rails, you need to insert `BetterErrors::Middleware` into your middleware stack, and optionally set `BetterErrors.application_root` if you'd like Better Errors to abbreviate filenames within your application.
63
+
64
+ Here's an example using Sinatra:
65
+
66
+ ```ruby
67
+ require "sinatra"
68
+ require "better_errors"
69
+
70
+ configure :development do
71
+ use BetterErrors::Middleware
72
+ BetterErrors.application_root = __dir__
73
+ end
74
+
75
+ get "/" do
76
+ raise "oops"
77
+ end
78
+ ```
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
+
85
+ ### Unicorn, Puma, and other multi-worker servers
86
+
87
+ Better Errors works by leaving a lot of context in server process memory. If
88
+ you're using a web server that runs multiple "workers" it's likely that a second
89
+ request (as happens when you click on a stack frame) will hit a different
90
+ worker. That worker won't have the necessary context in memory, and you'll see
91
+ a `Session Expired` message.
92
+
93
+ If this is the case for you, consider turning the number of workers to one (1)
94
+ in `development`. Another option would be to use Webrick, Mongrel, Thin,
95
+ or another single-process server as your `rails server`, when you are trying
96
+ to troubleshoot an issue in development.
97
+
98
+ ##Specify editor to open files in
99
+
100
+ ```ruby
101
+ # e.g. in config/initializers/better_errors.rb
102
+ # Other preset values are [:mvim, :macvim, :textmate, :txmt, :tm, :sublime, :subl, :st]
103
+ BetterErrors.editor = :mvim
104
+ ```
105
+
106
+
107
+ ##Set maximum variable size for inspector.
108
+
109
+ ```ruby
110
+ # e.g. in config/initializers/better_errors.rb
111
+ # This will stop BetterErrors from trying to render larger objects, which can cause
112
+ # slow loading times and browser performance problems.
113
+ # default value: 100_000
114
+ BetterErrors.maximum_variable_inspect_size = 100_000
115
+ ```
116
+
117
+
118
+ ## Get in touch!
119
+
120
+ If you're using better_errors, I'd love to hear from you. Drop me a line and tell me what you think!
121
+
122
+ ## Contributing
123
+
124
+ 1. Fork it
125
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
126
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
127
+ 4. Push to the branch (`git push origin my-new-feature`)
128
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ namespace :test do
5
+ RSpec::Core::RakeTask.new(:with_binding_of_caller)
6
+
7
+ without_task = RSpec::Core::RakeTask.new(:without_binding_of_caller)
8
+ without_task.ruby_opts = "-I spec -r without_binding_of_caller"
9
+
10
+ task :all => [:with_binding_of_caller, :without_binding_of_caller]
11
+ end
12
+
13
+ task :default => "test:all"
@@ -0,0 +1,28 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'better_errors/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "better_errors-creditkudos"
7
+ s.version = BetterErrors::VERSION
8
+ s.authors = ["Charlie Somerville"]
9
+ s.email = ["charlie@charliesomerville.com"]
10
+ s.description = %q{Temporary fork of better_errors with some performance improvements.}
11
+ s.summary = %q{Temporary fork of better_errors with some performance improvements.}
12
+ s.homepage = "https://github.com/creditkudos/better_errors"
13
+ s.license = "MIT"
14
+
15
+ s.files = `git ls-files`.split($/)
16
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
17
+ s.require_paths = ["lib"]
18
+
19
+ s.required_ruby_version = ">= 2.0.0"
20
+
21
+ s.add_dependency "erubis", ">= 2.6.6"
22
+ s.add_dependency "coderay", ">= 1.0.0"
23
+ s.add_dependency "rack", ">= 0.9.0"
24
+
25
+ # optional dependencies:
26
+ # s.add_dependency "binding_of_caller"
27
+ # s.add_dependency "pry"
28
+ end
@@ -0,0 +1,152 @@
1
+ require "pp"
2
+ require "erubis"
3
+ require "coderay"
4
+ require "uri"
5
+
6
+ require "better_errors/code_formatter"
7
+ require "better_errors/error_page"
8
+ require "better_errors/middleware"
9
+ require "better_errors/raised_exception"
10
+ require "better_errors/repl"
11
+ require "better_errors/stack_frame"
12
+ require "better_errors/version"
13
+
14
+ module BetterErrors
15
+ POSSIBLE_EDITOR_PRESETS = [
16
+ { symbols: [:emacs, :emacsclient], sniff: /emacs/i, url: "emacs://open?url=file://%{file}&line=%{line}" },
17
+ { symbols: [:macvim, :mvim], sniff: /vim/i, url: proc { |file, line| "mvim://open?url=file://#{file}&line=#{line}" } },
18
+ { symbols: [:sublime, :subl, :st], sniff: /subl/i, url: "subl://open?url=file://%{file}&line=%{line}" },
19
+ { symbols: [:textmate, :txmt, :tm], sniff: /mate/i, url: "txmt://open?url=file://%{file}&line=%{line}" },
20
+ ]
21
+
22
+ class << self
23
+ # The path to the root of the application. Better Errors uses this property
24
+ # to determine if a file in a backtrace should be considered an application
25
+ # frame. If you are using Better Errors with Rails, you do not need to set
26
+ # this attribute manually.
27
+ #
28
+ # @return [String]
29
+ attr_accessor :application_root
30
+
31
+ # The logger to use when logging exception details and backtraces. If you
32
+ # are using Better Errors with Rails, you do not need to set this attribute
33
+ # manually. If this attribute is `nil`, nothing will be logged.
34
+ #
35
+ # @return [Logger, nil]
36
+ attr_accessor :logger
37
+
38
+ # @private
39
+ attr_accessor :binding_of_caller_available
40
+
41
+ # @private
42
+ alias_method :binding_of_caller_available?, :binding_of_caller_available
43
+
44
+ # The ignored instance variables.
45
+ # @return [Array]
46
+ attr_accessor :ignored_instance_variables
47
+
48
+ # The maximum variable payload size. If variable.inspect exceeds this,
49
+ # the variable won't be returned.
50
+ # @return int
51
+ attr_accessor :maximum_variable_inspect_size
52
+ end
53
+ @ignored_instance_variables = []
54
+
55
+ # Returns a proc, which when called with a filename and line number argument,
56
+ # returns a URL to open the filename and line in the selected editor.
57
+ #
58
+ # Generates TextMate URLs by default.
59
+ #
60
+ # BetterErrors.editor["/some/file", 123]
61
+ # # => txmt://open?url=file:///some/file&line=123
62
+ #
63
+ # @return [Proc]
64
+ def self.editor
65
+ @editor
66
+ end
67
+
68
+ # Configures how Better Errors generates open-in-editor URLs.
69
+ #
70
+ # @overload BetterErrors.editor=(sym)
71
+ # Uses one of the preset editor configurations. Valid symbols are:
72
+ #
73
+ # * `:textmate`, `:txmt`, `:tm`
74
+ # * `:sublime`, `:subl`, `:st`
75
+ # * `:macvim`
76
+ #
77
+ # @param [Symbol] sym
78
+ #
79
+ # @overload BetterErrors.editor=(str)
80
+ # Uses `str` as the format string for generating open-in-editor URLs.
81
+ #
82
+ # Use `%{file}` and `%{line}` as placeholders for the actual values.
83
+ #
84
+ # @example
85
+ # BetterErrors.editor = "my-editor://open?url=%{file}&line=%{line}"
86
+ #
87
+ # @param [String] str
88
+ #
89
+ # @overload BetterErrors.editor=(proc)
90
+ # Uses `proc` to generate open-in-editor URLs. The proc will be called
91
+ # with `file` and `line` parameters when a URL needs to be generated.
92
+ #
93
+ # Your proc should take care to escape `file` appropriately with
94
+ # `URI.encode_www_form_component` (please note that `URI.escape` is **not**
95
+ # a suitable substitute.)
96
+ #
97
+ # @example
98
+ # BetterErrors.editor = proc { |file, line|
99
+ # "my-editor://open?url=#{URI.encode_www_form_component file}&line=#{line}"
100
+ # }
101
+ #
102
+ # @param [Proc] proc
103
+ #
104
+ def self.editor=(editor)
105
+ POSSIBLE_EDITOR_PRESETS.each do |config|
106
+ if config[:symbols].include?(editor)
107
+ return self.editor = config[:url]
108
+ end
109
+ end
110
+
111
+ if editor.is_a? String
112
+ self.editor = proc { |file, line| editor % { file: URI.encode_www_form_component(file), line: line } }
113
+ else
114
+ if editor.respond_to? :call
115
+ @editor = editor
116
+ else
117
+ raise TypeError, "Expected editor to be a valid editor key, a format string or a callable."
118
+ end
119
+ end
120
+ end
121
+
122
+ # Enables experimental Pry support in the inline REPL
123
+ #
124
+ # If you encounter problems while using Pry, *please* file a bug report at
125
+ # https://github.com/charliesome/better_errors/issues
126
+ def self.use_pry!
127
+ REPL::PROVIDERS.unshift const: :Pry, impl: "better_errors/repl/pry"
128
+ end
129
+
130
+ # Automatically sniffs a default editor preset based on the EDITOR
131
+ # environment variable.
132
+ #
133
+ # @return [Symbol]
134
+ def self.default_editor
135
+ POSSIBLE_EDITOR_PRESETS.detect(-> { {} }) { |config|
136
+ ENV["EDITOR"] =~ config[:sniff]
137
+ }[:url] || :textmate
138
+ end
139
+
140
+ BetterErrors.editor = default_editor
141
+ end
142
+
143
+ begin
144
+ require "binding_of_caller"
145
+ require "better_errors/exception_extension"
146
+ BetterErrors.binding_of_caller_available = true
147
+ BetterErrors.maximum_variable_inspect_size ||= 100_000
148
+ rescue LoadError
149
+ BetterErrors.binding_of_caller_available = false
150
+ end
151
+
152
+ require "better_errors/rails" if defined? Rails::Railtie
@@ -0,0 +1,63 @@
1
+ module BetterErrors
2
+ # @private
3
+ class CodeFormatter
4
+ require "better_errors/code_formatter/html"
5
+ require "better_errors/code_formatter/text"
6
+
7
+ FILE_TYPES = {
8
+ ".rb" => :ruby,
9
+ "" => :ruby,
10
+ ".html" => :html,
11
+ ".erb" => :erb,
12
+ ".haml" => :haml
13
+ }
14
+
15
+ attr_reader :filename, :line, :context
16
+
17
+ def initialize(filename, line, context = 5)
18
+ @filename = filename
19
+ @line = line
20
+ @context = context
21
+ end
22
+
23
+ def output
24
+ formatted_code
25
+ rescue Errno::ENOENT, Errno::EINVAL
26
+ source_unavailable
27
+ end
28
+
29
+ def formatted_code
30
+ formatted_lines.join
31
+ end
32
+
33
+ def coderay_scanner
34
+ ext = File.extname(filename)
35
+ FILE_TYPES[ext] || :text
36
+ end
37
+
38
+ def each_line_of(lines, &blk)
39
+ line_range.zip(lines).map { |current_line, str|
40
+ yield (current_line == line), current_line, str
41
+ }
42
+ end
43
+
44
+ def highlighted_lines
45
+ CodeRay.scan(context_lines.join, coderay_scanner).div(wrap: nil).lines
46
+ end
47
+
48
+ def context_lines
49
+ range = line_range
50
+ source_lines[(range.begin - 1)..(range.end - 1)] or raise Errno::EINVAL
51
+ end
52
+
53
+ def source_lines
54
+ @source_lines ||= File.readlines(filename)
55
+ end
56
+
57
+ def line_range
58
+ min = [line - context, 1].max
59
+ max = [line + context, source_lines.count].min
60
+ min..max
61
+ end
62
+ end
63
+ end