better_errors 1.0.0 → 2.9.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.
- checksums.yaml +5 -5
- data/.coveralls.yml +1 -0
- data/.github/workflows/ci.yml +130 -0
- data/.github/workflows/release.yml +64 -0
- data/.gitignore +10 -5
- data/.ruby-version +1 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +7 -7
- data/LICENSE.txt +1 -1
- data/README.md +103 -33
- data/better_errors.gemspec +26 -8
- data/gemfiles/pry010.gemfile +10 -0
- data/gemfiles/pry011.gemfile +9 -0
- data/gemfiles/pry09.gemfile +9 -0
- data/gemfiles/rack.gemfile +8 -0
- data/gemfiles/rack_boc.gemfile +9 -0
- data/gemfiles/rails42.gemfile +10 -0
- data/gemfiles/rails42_boc.gemfile +11 -0
- data/gemfiles/rails42_haml.gemfile +11 -0
- data/gemfiles/rails50.gemfile +9 -0
- data/gemfiles/rails50_boc.gemfile +10 -0
- data/gemfiles/rails50_haml.gemfile +10 -0
- data/gemfiles/rails51.gemfile +9 -0
- data/gemfiles/rails51_boc.gemfile +10 -0
- data/gemfiles/rails51_haml.gemfile +10 -0
- data/gemfiles/rails52.gemfile +9 -0
- data/gemfiles/rails52_boc.gemfile +10 -0
- data/gemfiles/rails52_haml.gemfile +10 -0
- data/gemfiles/rails60.gemfile +8 -0
- data/gemfiles/rails60_boc.gemfile +9 -0
- data/gemfiles/rails60_haml.gemfile +9 -0
- data/lib/better_errors/code_formatter/html.rb +1 -1
- data/lib/better_errors/code_formatter.rb +7 -7
- data/lib/better_errors/editor.rb +99 -0
- data/lib/better_errors/error_page.rb +83 -49
- data/lib/better_errors/exception_extension.rb +17 -0
- data/lib/better_errors/exception_hint.rb +29 -0
- data/lib/better_errors/inspectable_value.rb +45 -0
- data/lib/better_errors/middleware.rb +101 -21
- data/lib/better_errors/raised_exception.rb +89 -0
- data/lib/better_errors/repl/basic.rb +3 -3
- data/lib/better_errors/repl/pry.rb +20 -10
- data/lib/better_errors/repl.rb +6 -4
- data/lib/better_errors/stack_frame.rb +48 -71
- data/lib/better_errors/templates/main.erb +167 -94
- data/lib/better_errors/templates/text.erb +6 -3
- data/lib/better_errors/templates/variable_info.erb +33 -24
- data/lib/better_errors/version.rb +1 -1
- data/lib/better_errors.rb +35 -37
- metadata +150 -46
- data/.travis.yml +0 -6
- data/Rakefile +0 -4
- data/ext/mkrf_conf.rb +0 -11
- data/lib/better_errors/core_ext/exception.rb +0 -21
- data/spec/better_errors/code_formatter_spec.rb +0 -92
- data/spec/better_errors/error_page_spec.rb +0 -76
- data/spec/better_errors/middleware_spec.rb +0 -112
- data/spec/better_errors/repl/basic_spec.rb +0 -18
- data/spec/better_errors/repl/pry_spec.rb +0 -36
- data/spec/better_errors/repl/shared_examples.rb +0 -18
- data/spec/better_errors/stack_frame_spec.rb +0 -161
- data/spec/better_errors/support/my_source.rb +0 -20
- data/spec/better_errors_spec.rb +0 -73
- data/spec/spec_helper.rb +0 -7
|
@@ -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
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require "uri"
|
|
2
|
+
|
|
3
|
+
module BetterErrors
|
|
4
|
+
class Editor
|
|
5
|
+
KNOWN_EDITORS = [
|
|
6
|
+
{ symbols: [:atom], sniff: /atom/i, url: "atom://core/open/file?filename=%{file}&line=%{line}" },
|
|
7
|
+
{ symbols: [:emacs, :emacsclient], sniff: /emacs/i, url: "emacs://open?url=file://%{file}&line=%{line}" },
|
|
8
|
+
{ symbols: [:idea], sniff: /idea/i, url: "idea://open?file=%{file}&line=%{line}" },
|
|
9
|
+
{ symbols: [:macvim, :mvim], sniff: /vim/i, url: "mvim://open?url=file://%{file_unencoded}&line=%{line}" },
|
|
10
|
+
{ symbols: [:rubymine], sniff: /mine/i, url: "x-mine://open?file=%{file}&line=%{line}" },
|
|
11
|
+
{ symbols: [:sublime, :subl, :st], sniff: /subl/i, url: "subl://open?url=file://%{file}&line=%{line}" },
|
|
12
|
+
{ symbols: [:textmate, :txmt, :tm], sniff: /mate/i, url: "txmt://open?url=file://%{file}&line=%{line}" },
|
|
13
|
+
{ symbols: [:vscode, :code], sniff: /code/i, url: "vscode://file/%{file}:%{line}" },
|
|
14
|
+
{ symbols: [:vscodium, :codium], sniff: /codium/i, url: "vscodium://file/%{file}:%{line}" },
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
def self.for_formatting_string(formatting_string)
|
|
18
|
+
new proc { |file, line|
|
|
19
|
+
formatting_string % { file: URI.encode_www_form_component(file), file_unencoded: file, line: line }
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.for_proc(url_proc)
|
|
24
|
+
new url_proc
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Automatically sniffs a default editor preset based on
|
|
28
|
+
# environment variables.
|
|
29
|
+
#
|
|
30
|
+
# @return [Symbol]
|
|
31
|
+
def self.default_editor
|
|
32
|
+
editor_from_environment_formatting_string ||
|
|
33
|
+
editor_from_environment_editor ||
|
|
34
|
+
editor_from_symbol(:textmate)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.editor_from_environment_editor
|
|
38
|
+
if ENV["BETTER_ERRORS_EDITOR"]
|
|
39
|
+
editor = editor_from_command(ENV["BETTER_ERRORS_EDITOR"])
|
|
40
|
+
return editor if editor
|
|
41
|
+
puts "BETTER_ERRORS_EDITOR environment variable is not recognized as a supported Better Errors editor."
|
|
42
|
+
end
|
|
43
|
+
if ENV["EDITOR"]
|
|
44
|
+
editor = editor_from_command(ENV["EDITOR"])
|
|
45
|
+
return editor if editor
|
|
46
|
+
puts "EDITOR environment variable is not recognized as a supported Better Errors editor. Using TextMate by default."
|
|
47
|
+
else
|
|
48
|
+
puts "Since there is no EDITOR or BETTER_ERRORS_EDITOR environment variable, using Textmate by default."
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.editor_from_command(editor_command)
|
|
53
|
+
env_preset = KNOWN_EDITORS.find { |preset| editor_command =~ preset[:sniff] }
|
|
54
|
+
for_formatting_string(env_preset[:url]) if env_preset
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.editor_from_environment_formatting_string
|
|
58
|
+
return unless ENV['BETTER_ERRORS_EDITOR_URL']
|
|
59
|
+
|
|
60
|
+
for_formatting_string(ENV['BETTER_ERRORS_EDITOR_URL'])
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.editor_from_symbol(symbol)
|
|
64
|
+
KNOWN_EDITORS.each do |preset|
|
|
65
|
+
return for_formatting_string(preset[:url]) if preset[:symbols].include?(symbol)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def initialize(url_proc)
|
|
70
|
+
@url_proc = url_proc
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def url(raw_path, line)
|
|
74
|
+
if virtual_path && raw_path.start_with?(virtual_path)
|
|
75
|
+
if host_path
|
|
76
|
+
file = raw_path.sub(%r{\A#{virtual_path}}, host_path)
|
|
77
|
+
else
|
|
78
|
+
file = raw_path.sub(%r{\A#{virtual_path}/}, '')
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
file = raw_path
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
url_proc.call(file, line)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
attr_reader :url_proc
|
|
90
|
+
|
|
91
|
+
def virtual_path
|
|
92
|
+
@virtual_path ||= ENV['BETTER_ERRORS_VIRTUAL_PATH']
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def host_path
|
|
96
|
+
@host_path ||= ENV['BETTER_ERRORS_HOST_PATH']
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "cgi"
|
|
2
2
|
require "json"
|
|
3
|
+
require "securerandom"
|
|
3
4
|
|
|
4
5
|
module BetterErrors
|
|
5
6
|
# @private
|
|
@@ -7,65 +8,95 @@ module BetterErrors
|
|
|
7
8
|
def self.template_path(template_name)
|
|
8
9
|
File.expand_path("../templates/#{template_name}.erb", __FILE__)
|
|
9
10
|
end
|
|
10
|
-
|
|
11
|
+
|
|
11
12
|
def self.template(template_name)
|
|
12
|
-
|
|
13
|
+
Erubi::Engine.new(File.read(template_path(template_name)), escape: true)
|
|
13
14
|
end
|
|
14
|
-
|
|
15
|
+
|
|
15
16
|
attr_reader :exception, :env, :repls
|
|
16
|
-
|
|
17
|
+
|
|
17
18
|
def initialize(exception, env)
|
|
18
|
-
@exception =
|
|
19
|
+
@exception = RaisedException.new(exception)
|
|
19
20
|
@env = env
|
|
20
21
|
@start_time = Time.now.to_f
|
|
21
22
|
@repls = []
|
|
22
23
|
end
|
|
23
|
-
|
|
24
|
-
def
|
|
25
|
-
|
|
24
|
+
|
|
25
|
+
def id
|
|
26
|
+
@id ||= SecureRandom.hex(8)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def render(template_name = "main", csrf_token = nil)
|
|
30
|
+
binding.eval(self.class.template(template_name).src)
|
|
31
|
+
rescue => e
|
|
32
|
+
# Fix the backtrace, which doesn't identify the template that failed (within Better Errors).
|
|
33
|
+
# We don't know the line number, so just injecting the template path has to be enough.
|
|
34
|
+
e.backtrace.unshift "#{self.class.template_path(template_name)}:0"
|
|
35
|
+
raise
|
|
26
36
|
end
|
|
27
|
-
|
|
37
|
+
|
|
28
38
|
def do_variables(opts)
|
|
29
39
|
index = opts["index"].to_i
|
|
30
40
|
@frame = backtrace_frames[index]
|
|
31
41
|
@var_start_time = Time.now.to_f
|
|
32
42
|
{ html: render("variable_info") }
|
|
33
43
|
end
|
|
34
|
-
|
|
44
|
+
|
|
35
45
|
def do_eval(opts)
|
|
36
46
|
index = opts["index"].to_i
|
|
37
47
|
code = opts["source"]
|
|
38
|
-
|
|
39
|
-
unless binding = backtrace_frames[index].frame_binding
|
|
48
|
+
|
|
49
|
+
unless (binding = backtrace_frames[index].frame_binding)
|
|
40
50
|
return { error: "REPL unavailable in this stack frame" }
|
|
41
51
|
end
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
{ result: result,
|
|
47
|
-
prompt: prompt,
|
|
48
|
-
prefilled_input: prefilled_input,
|
|
49
|
-
highlighted_input: CodeRay.scan(code, :ruby).div(wrap: nil) }
|
|
52
|
+
|
|
53
|
+
@repls[index] ||= REPL.provider.new(binding, exception)
|
|
54
|
+
|
|
55
|
+
eval_and_respond(index, code)
|
|
50
56
|
end
|
|
51
57
|
|
|
52
58
|
def backtrace_frames
|
|
53
|
-
|
|
59
|
+
exception.backtrace
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def exception_type
|
|
63
|
+
exception.type
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def exception_message
|
|
67
|
+
exception.message.strip.gsub(/(\r?\n\s*\r?\n)+/, "\n")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def exception_hint
|
|
71
|
+
exception.hint
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def active_support_actions
|
|
75
|
+
return [] unless defined?(ActiveSupport::ActionableError)
|
|
76
|
+
|
|
77
|
+
ActiveSupport::ActionableError.actions(exception.type)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def action_dispatch_action_endpoint
|
|
81
|
+
return unless defined?(ActionDispatch::ActionableExceptions)
|
|
82
|
+
|
|
83
|
+
ActionDispatch::ActionableExceptions.endpoint
|
|
54
84
|
end
|
|
55
85
|
|
|
56
86
|
def application_frames
|
|
57
|
-
backtrace_frames.select
|
|
87
|
+
backtrace_frames.select(&:application?)
|
|
58
88
|
end
|
|
59
89
|
|
|
60
90
|
def first_frame
|
|
61
|
-
|
|
91
|
+
application_frames.first || backtrace_frames.first
|
|
62
92
|
end
|
|
63
|
-
|
|
64
|
-
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
65
96
|
def editor_url(frame)
|
|
66
|
-
BetterErrors.editor
|
|
97
|
+
BetterErrors.editor.url(frame.filename, frame.line)
|
|
67
98
|
end
|
|
68
|
-
|
|
99
|
+
|
|
69
100
|
def rack_session
|
|
70
101
|
env['rack.session']
|
|
71
102
|
end
|
|
@@ -77,31 +108,15 @@ module BetterErrors
|
|
|
77
108
|
def uri_prefix
|
|
78
109
|
env["SCRIPT_NAME"] || ""
|
|
79
110
|
end
|
|
80
|
-
|
|
81
|
-
def exception_message
|
|
82
|
-
if exception.is_a?(SyntaxError) && exception.message =~ /\A.*:\d*: (.*)$/
|
|
83
|
-
$1
|
|
84
|
-
else
|
|
85
|
-
exception.message
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
111
|
|
|
89
|
-
def real_exception(exception)
|
|
90
|
-
if exception.respond_to? :original_exception
|
|
91
|
-
exception.original_exception
|
|
92
|
-
else
|
|
93
|
-
exception
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
112
|
def request_path
|
|
98
113
|
env["PATH_INFO"]
|
|
99
114
|
end
|
|
100
|
-
|
|
115
|
+
|
|
101
116
|
def html_formatted_code_block(frame)
|
|
102
117
|
CodeFormatter::HTML.new(frame.filename, frame.line).output
|
|
103
118
|
end
|
|
104
|
-
|
|
119
|
+
|
|
105
120
|
def text_formatted_code_block(frame)
|
|
106
121
|
CodeFormatter::Text.new(frame.filename, frame.line).output
|
|
107
122
|
end
|
|
@@ -111,11 +126,30 @@ module BetterErrors
|
|
|
111
126
|
end
|
|
112
127
|
|
|
113
128
|
def inspect_value(obj)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
129
|
+
if BetterErrors.ignored_classes.include? obj.class.name
|
|
130
|
+
"<span class='unsupported'>(Instance of ignored class. "\
|
|
131
|
+
"#{obj.class.name ? "Remove #{CGI.escapeHTML(obj.class.name)} from" : "Modify"}"\
|
|
132
|
+
" BetterErrors.ignored_classes if you need to see it.)</span>"
|
|
133
|
+
else
|
|
134
|
+
InspectableValue.new(obj).to_html
|
|
135
|
+
end
|
|
136
|
+
rescue BetterErrors::ValueLargerThanConfiguredMaximum
|
|
137
|
+
"<span class='unsupported'>(Object too large. "\
|
|
138
|
+
"#{obj.class.name ? "Modify #{CGI.escapeHTML(obj.class.name)}#inspect or a" : "A"}"\
|
|
139
|
+
"djust BetterErrors.maximum_variable_inspect_size if you need to see it.)</span>"
|
|
117
140
|
rescue Exception => e
|
|
118
|
-
"<span class='unsupported'>(exception was raised in inspect)</span>"
|
|
141
|
+
"<span class='unsupported'>(exception #{CGI.escapeHTML(e.class.to_s)} was raised in inspect)</span>"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def eval_and_respond(index, code)
|
|
145
|
+
result, prompt, prefilled_input = @repls[index].send_input(code)
|
|
146
|
+
|
|
147
|
+
{
|
|
148
|
+
highlighted_input: CodeRay.scan(code, :ruby).div(wrap: nil),
|
|
149
|
+
prefilled_input: prefilled_input,
|
|
150
|
+
prompt: prompt,
|
|
151
|
+
result: result
|
|
152
|
+
}
|
|
119
153
|
end
|
|
120
154
|
end
|
|
121
155
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module BetterErrors
|
|
2
|
+
module ExceptionExtension
|
|
3
|
+
prepend_features Exception
|
|
4
|
+
|
|
5
|
+
def set_backtrace(*)
|
|
6
|
+
if caller_locations.none? { |loc| loc.path == __FILE__ }
|
|
7
|
+
@__better_errors_bindings_stack = ::Kernel.binding.callers.drop(1)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def __better_errors_bindings_stack
|
|
14
|
+
@__better_errors_bindings_stack || []
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module BetterErrors
|
|
2
|
+
class ExceptionHint
|
|
3
|
+
def initialize(exception)
|
|
4
|
+
@exception = exception
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def hint
|
|
8
|
+
case exception
|
|
9
|
+
when NoMethodError
|
|
10
|
+
/\Aundefined method `(?<method>[^']+)' for (?<val>[^:]+):(?<klass>\w+)/.match(exception.message) do |match|
|
|
11
|
+
if match[:val] == "nil"
|
|
12
|
+
return "Something is `nil` when it probably shouldn't be."
|
|
13
|
+
elsif !match[:klass].start_with? '0x'
|
|
14
|
+
return "`#{match[:method]}` is being called on a `#{match[:klass]}` object, "\
|
|
15
|
+
"which might not be the type of object you were expecting."
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
when NameError
|
|
19
|
+
/\Aundefined local variable or method `(?<method>[^']+)' for/.match(exception.message) do |match|
|
|
20
|
+
return "`#{match[:method]}` is probably misspelled."
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
attr_reader :exception
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require "cgi"
|
|
2
|
+
require "objspace" rescue nil
|
|
3
|
+
|
|
4
|
+
module BetterErrors
|
|
5
|
+
class ValueLargerThanConfiguredMaximum < StandardError; end
|
|
6
|
+
|
|
7
|
+
class InspectableValue
|
|
8
|
+
def initialize(value)
|
|
9
|
+
@original_value = value
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_html
|
|
13
|
+
raise ValueLargerThanConfiguredMaximum unless value_small_enough_to_inspect?
|
|
14
|
+
value_as_html
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
attr_reader :original_value
|
|
20
|
+
|
|
21
|
+
def value_as_html
|
|
22
|
+
@value_as_html ||= CGI.escapeHTML(value)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def value
|
|
26
|
+
@value ||= begin
|
|
27
|
+
if original_value.respond_to? :inspect
|
|
28
|
+
original_value.inspect
|
|
29
|
+
else
|
|
30
|
+
original_value
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def value_small_enough_to_inspect?
|
|
36
|
+
return true if BetterErrors.maximum_variable_inspect_size.nil?
|
|
37
|
+
|
|
38
|
+
if defined?(ObjectSpace) && defined?(ObjectSpace.memsize_of) && ObjectSpace.memsize_of(value)
|
|
39
|
+
ObjectSpace.memsize_of(value) <= BetterErrors.maximum_variable_inspect_size
|
|
40
|
+
else
|
|
41
|
+
value_as_html.length <= BetterErrors.maximum_variable_inspect_size
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|