Skip to content

Commit b979afe

Browse files
authored
Merge pull request rails#48957 from cmaruz/48326
Better handle SyntaxError in Action View
2 parents c4733f3 + df6d2fb commit b979afe

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

actionpack/lib/action_dispatch/middleware/exception_wrapper.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def initialize(location, template)
242242
end
243243

244244
def spot(exc)
245-
if RubyVM::AbstractSyntaxTree.respond_to?(:node_id_for_backtrace_location)
245+
if RubyVM::AbstractSyntaxTree.respond_to?(:node_id_for_backtrace_location) && __getobj__.is_a?(Thread::Backtrace::Location)
246246
location = @template.spot(__getobj__)
247247
else
248248
location = super
@@ -267,7 +267,12 @@ def build_backtrace
267267

268268
(@exception.backtrace_locations || []).map do |loc|
269269
if built_methods.key?(loc.label.to_s)
270-
SourceMapLocation.new(loc, built_methods[loc.label.to_s])
270+
thread_backtrace_location = if loc.respond_to?(:__getobj__)
271+
loc.__getobj__
272+
else
273+
loc
274+
end
275+
SourceMapLocation.new(thread_backtrace_location, built_methods[loc.label.to_s])
271276
else
272277
loc
273278
end

actionpack/test/dispatch/exception_wrapper_test.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,20 @@ def backtrace
6969
end
7070
end
7171

72+
class_eval "def throw_syntax_error; eval %(
73+
'abc' + pluralize 'def'
74+
); end", "lib/file.rb", 42
75+
76+
test "#source_extracts works with eval syntax error" do
77+
exception = begin throw_syntax_error; rescue SyntaxError => ex; ex; end
78+
79+
wrapper = ExceptionWrapper.new(nil, TopErrorProxy.new(exception, 1))
80+
81+
assert_called_with(wrapper, :source_fragment, ["lib/file.rb", 42], returns: "foo") do
82+
assert_equal [ code: "foo", line_number: 42 ], wrapper.source_extracts
83+
end
84+
end
85+
7286
if defined?(ErrorHighlight) && Gem::Version.new(ErrorHighlight::VERSION) >= Gem::Version.new("0.4.0")
7387
test "#source_extracts works with error_highlight" do
7488
lineno = __LINE__

activesupport/lib/active_support/syntax_error_proxy.rb

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,26 @@ def backtrace_locations
4343

4444
private
4545
def parse_message_for_trace
46-
__getobj__.to_s.split("\n")
46+
if source_location_eval?
47+
# If the exception is coming from a call to eval, we need to keep
48+
# the path of the file in which eval was called to ensure we can
49+
# return the right source fragment to show the location of the
50+
# error
51+
location = __getobj__.backtrace_locations[0]
52+
["#{location.path}:#{location.lineno}: #{__getobj__}"]
53+
else
54+
__getobj__.to_s.split("\n")
55+
end
56+
end
57+
58+
if SyntaxError.method_defined?(:path) # Ruby 3.3+
59+
def source_location_eval?
60+
__getobj__.path.start_with?("(eval")
61+
end
62+
else # 3.2 and older versions of Ruby
63+
def source_location_eval?
64+
__getobj__.to_s.start_with?("(eval")
65+
end
4766
end
4867
end
4968
end

0 commit comments

Comments
 (0)