FIX: Do not block SVG sprite bundle if a file is missing (#13338)

FIX: Do not block SVG sprite bundle if a file is missing (#13338)

diff --git a/lib/svg_sprite/svg_sprite.rb b/lib/svg_sprite/svg_sprite.rb
index 79bef31..b2010fe 100644
--- a/lib/svg_sprite/svg_sprite.rb
+++ b/lib/svg_sprite/svg_sprite.rb
@@ -330,6 +330,11 @@ License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL
     end
 
     custom_svg_sprites(theme_ids).each do |fname|
+      if !File.exist?(fname)
+        cache.delete("custom_svg_sprites_#{Theme.transform_ids(theme_ids).join(',')}")
+        next
+      end
+
       svg_file = Nokogiri::XML(File.open(fname)) do |config|
         config.options = Nokogiri::XML::ParseOptions::NOBLANKS
       end
@@ -354,6 +359,8 @@ License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL
     searched_icon = process(searched_icon.dup)
 
     sprite_sources([SiteSetting.default_theme_id]).each do |fname|
+      next if !File.exist?(fname)
+
       svg_file = Nokogiri::XML(File.open(fname))
       svg_filename = "#{File.basename(fname, ".svg")}"
 
@@ -375,6 +382,8 @@ License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL
     results = Set.new
 
     sprite_sources([SiteSetting.default_theme_id]).each do |fname|
+      next if !File.exist?(fname)
+
       svg_file = Nokogiri::XML(File.open(fname))
       svg_filename = "#{File.basename(fname, ".svg")}"
 
@@ -475,6 +484,8 @@ License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL
     # Automatically register icons in sprites added via themes or plugins
     icons = []
     custom_svg_sprites(theme_ids).each do |fname|
+      next if !File.exist?(fname)
+
       svg_file = Nokogiri::XML(File.open(fname))
 
       svg_file.css('symbol').each do |sym|
diff --git a/spec/components/svg_sprite/svg_sprite_spec.rb b/spec/components/svg_sprite/svg_sprite_spec.rb
index abb39b1..bce3820 100644
--- a/spec/components/svg_sprite/svg_sprite_spec.rb
+++ b/spec/components/svg_sprite/svg_sprite_spec.rb
@@ -165,7 +165,15 @@ describe SvgSprite do
 
     before do
       setup_s3
-      stub_request(:get, upload_s3.url).to_return(status: 200, body: "Hello world")
+      body = <<~XML
+        <?xml version="1.0" encoding="UTF-8"?>
+        <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
+          <symbol id="my-custom-theme-icon" viewBox="0 0 496 512">
+            <path d="M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm0 376c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-128c-53.02 0-96 42.98-96 96s42.98 96 96 96c-106.04 0-192-85.96-192-192S141.96 64 248 64c53.02 0 96 42.98 96 96s-42.98 96-96 96zm0-128c-17.67 0-32 14.33-32 32s14.33 32 32 32 32-14.33 32-32-14.33-32-32-32z"></path>
+          </symbol>
+        </svg>
+      XML
+      stub_request(:get, upload_s3.url).to_return(status: 200, body: body)
     end
 
     it 'includes svg sprites in themes stored in s3' do
@@ -174,9 +182,19 @@ describe SvgSprite do
       theme.save!
 
       sprite_files = SvgSprite.custom_svg_sprites([theme.id]).join("|")
-
       expect(sprite_files).to match(/#{upload_s3.sha1}/)
       expect(sprite_files).not_to match(/amazonaws/)
+
+      SvgSprite.bundle([theme.id])
+      expect(SvgSprite.cache.hash.keys).to include("custom_svg_sprites_#{theme.id}")
+
+      external_copy = Discourse.store.download(upload_s3)
+      File.delete external_copy.try(:path)
+
+      SvgSprite.bundle([theme.id])
+      # when a file is missing, ensure that cache entry is cleared
+      expect(SvgSprite.cache.hash.keys).to_not include("custom_svg_sprites_#{theme.id}")
+
     end
   end
 

GitHub sha: a96f6fbdf5a35710269fd6e230826d3e1cdbec1c

This commit appears in #13338 which was approved by SamSaffron. It was merged by pmusaraj.