better_errors-creditkudos 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
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