From 274e18622efcbf7e4c9861bba5b9e66a2c17f3cb Mon Sep 17 00:00:00 2001
From: Blake Erickson <o.blakeerickson@gmail.com>
Date: Fri, 23 Aug 2024 15:58:54 -0600
Subject: [PATCH] FIX: Video uploads sometimes hang indefinitely (#28523)

If there is a codec issue or something trying to process a video file
for thumbnail generation, uploads could hang indefinitely. This fix
  ensures that we continue the upload process even if we encounter an
  error trying to generate a thumbnail for it.
---
 .../mixins/composer-video-thumbnail-uppy.js   |  8 +++++++
 spec/system/composer_uploads_spec.rb          | 21 +++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/app/assets/javascripts/discourse/app/mixins/composer-video-thumbnail-uppy.js b/app/assets/javascripts/discourse/app/mixins/composer-video-thumbnail-uppy.js
index 4e19080b77c..56f344543bc 100644
--- a/app/assets/javascripts/discourse/app/mixins/composer-video-thumbnail-uppy.js
+++ b/app/assets/javascripts/discourse/app/mixins/composer-video-thumbnail-uppy.js
@@ -162,5 +162,13 @@ export default class ComposerVideoThumbnailUppy extends EmberObject.extend(
         }
       }, 100);
     };
+
+    video.onerror = () => {
+      // eslint-disable-next-line no-console
+      console.warn(
+        "Video could not be loaded or decoded for thumbnail generation"
+      );
+      callback();
+    };
   }
 }
diff --git a/spec/system/composer_uploads_spec.rb b/spec/system/composer_uploads_spec.rb
index 235a268c318..0a5b4e64f1a 100644
--- a/spec/system/composer_uploads_spec.rb
+++ b/spec/system/composer_uploads_spec.rb
@@ -117,6 +117,27 @@ describe "Uploading files in the composer", type: :system do
       end
     end
 
+    it "handles a video load error gracefully" do
+      visit "/new-topic"
+      expect(composer).to be_opened
+      topic.fill_in_composer_title("Video Load Error Test")
+
+      # Inject JavaScript to simulate an invalid video file that triggers onerror
+      page.execute_script <<-JS
+        const originalCreateObjectURL = URL.createObjectURL;
+        URL.createObjectURL = function(blob) {
+          // Simulate an invalid video source by returning a fake object URL
+          return 'invalid_video_source.mp4';
+        };
+      JS
+
+      file_path_1 = file_from_fixtures("small.mp4", "media").path
+      attach_file(file_path_1) { composer.click_toolbar_button("upload") }
+
+      expect(composer).to have_no_in_progress_uploads
+      expect(composer.preview).to have_css(".onebox-placeholder-container")
+    end
+
     it "shows video player in composer" do
       SiteSetting.enable_diffhtml_preview = true