Skip to content

Commit

Permalink
Be resilient to Zeitwerk::NameError in on_unload callbacks
Browse files Browse the repository at this point in the history
Fixes #208.
  • Loading branch information
fxn committed Jan 27, 2022
1 parent e88c817 commit 40b80df
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/zeitwerk/loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,13 @@ def unload
end

to_unload.each do |cpath, (abspath, (parent, cname))|
unless on_unload_callbacks.empty?
# We have to check cdef? in this condition. Reason is, constants whose
# file does not define them have to be kept in to_unload as explained
# in the implementation of on_file_autoloaded.
#
# If the constant is not defined, on_unload should not be triggered
# for it.
if !on_unload_callbacks.empty? && cdef?(parent, cname)
value = parent.const_get(cname)
run_on_unload_callbacks(cpath, value, abspath)
end
Expand Down
29 changes: 29 additions & 0 deletions test/lib/zeitwerk/test_reloading.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,33 @@ module Namespace; end
assert_equal 2, $test_eager_load_after_reload
end
end

test "reload recovers from name errors (w/o on_unload callbacks)" do
on_teardown { remove_const :Y }

files = [["x.rb", "Y = :typo"]]
with_setup(files) do
assert_raises(Zeitwerk::NameError) { X }

loader.reload
File.write("x.rb", "X = true")

assert X
end
end

test "reload recovers from name errors (w/ on_unload callbacks)" do
on_teardown { remove_const :Y }

files = [["x.rb", "Y = :typo"]]
with_setup(files) do
loader.on_unload {}
assert_raises(Zeitwerk::NameError) { X }

loader.reload
File.write("x.rb", "X = true")

assert X
end
end
end

0 comments on commit 40b80df

Please sign in to comment.