Skip to content

Show a warning message when the attachments URL are 404#16087

Merged
alecslupu merged 5 commits intodevelopfrom
fix/import-spaces-404-attachments
Feb 15, 2026
Merged

Show a warning message when the attachments URL are 404#16087
alecslupu merged 5 commits intodevelopfrom
fix/import-spaces-404-attachments

Conversation

@andreslucena
Copy link
Copy Markdown
Member

@andreslucena andreslucena commented Feb 11, 2026

🎩 What? Why?

As I mentioned in #16026, I found yet another bug in the import spaces flow. This is basically the same as the one in #16026, but this time with attachments: if the attachments don't exist, then we have an exception during the import process.

The proposed solution is by adding more warnings about this, so the admin can fix it afterwards.

📌 Related Issues

Testing

  1. Sign in as admin
  2. Export an assembly
  3. Change the URL of the attachments to an invalid URL
  4. Import this assembly at http://localhost:3000/admin/assemblies/imports/new - NOTE: do click in the "Import attachments" (as it is by default)
  5. (Without the patch) see the exception
  6. (With the patch) see the warning (and that the import still happens)

This is the assembly that I'm using for my local exploration:

assemblies-bad.json

Stacktrace

OpenURI::HTTPError (404 Not Found):

/home/vscode/.local/share/mise/installs/ruby/3.4.7/lib/ruby/3.4.0/open-uri.rb:393:in 'OpenURI.open_http'
/home/vscode/.local/share/mise/installs/ruby/3.4.7/lib/ruby/3.4.0/open-uri.rb:825:in 'URI::HTTP#buffer_open'
/home/vscode/.local/share/mise/installs/ruby/3.4.7/lib/ruby/3.4.0/open-uri.rb:233:in 'block in OpenURI.open_loop'
/home/vscode/.local/share/mise/installs/ruby/3.4.7/lib/ruby/3.4.0/open-uri.rb:231:in 'Kernel#catch'
/home/vscode/.local/share/mise/installs/ruby/3.4.7/lib/ruby/3.4.0/open-uri.rb:231:in 'OpenURI.open_loop'
/home/vscode/.local/share/mise/installs/ruby/3.4.7/lib/ruby/3.4.0/open-uri.rb:163:in 'OpenURI.open_uri'
/home/vscode/.local/share/mise/installs/ruby/3.4.7/lib/ruby/3.4.0/open-uri.rb:805:in 'OpenURI::OpenRead#open'
/workspaces/decidim/decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb:77:in 'block in Decidim::Assemblies::AssemblyImporter#import_folders_and_attachments'
/workspaces/decidim/decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb:74:in 'Array#map'
/workspaces/decidim/decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb:74:in 'Decidim::Assemblies::AssemblyImporter#import_folders_and_attachments'
/workspaces/decidim/decidim-assemblies/app/commands/decidim/assemblies/admin/import_assembly.rb:45:in 'block (2 levels) in Decidim::Assemblies::Admin::ImportAssembly#import_assembly'
/workspaces/decidim/decidim-core/app/services/decidim/traceability.rb:64:in 'block (2 levels) in Decidim::Traceability#perform_action!'
activerecord (7.2.2.2) lib/active_record/connection_adapters/abstract/database_statements.rb:359:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#transaction'
activerecord (7.2.2.2) lib/active_record/transactions.rb:234:in 'block in ActiveRecord::Transactions::ClassMethods#transaction'
activerecord (7.2.2.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:415:in 'ActiveRecord::ConnectionAdapters::ConnectionPool#with_connection'
activerecord (7.2.2.2) lib/active_record/connection_handling.rb:296:in 'ActiveRecord::ConnectionHandling#with_connection'
activerecord (7.2.2.2) lib/active_record/transactions.rb:233:in 'ActiveRecord::Transactions::ClassMethods#transaction'
/workspaces/decidim/decidim-core/app/services/decidim/traceability.rb:63:in 'block in Decidim::Traceability#perform_action!'
paper_trail (16.0.0) lib/paper_trail/request.rb:85:in 'PaperTrail::Request.with'
paper_trail (16.0.0) lib/paper_trail.rb:81:in 'PaperTrail.request'
/workspaces/decidim/decidim-core/app/services/decidim/traceability.rb:62:in 'Decidim::Traceability#perform_action!'

📷 Screenshots

Before

image

After

image

♥️ Thank you!

Summary by CodeRabbit

  • Bug Fixes

    • Attachment and image imports now validate remote URLs, handle network/time-out errors gracefully, and display clear, consistent warning messages including status/details so imports continue despite problematic files.
  • Documentation

    • Improved user-facing import error wording (hero/banner/attachment) for clearer, consistent messages that include the specific error detail.
  • Tests

    • Added/updated tests covering attachment and image import failures (404, 500, download errors) to ensure precise warning messages.

Copilot AI review requested due to automatic review settings February 11, 2026 15:17
@andreslucena andreslucena added the type: fix PRs that implement a fix for a bug label Feb 11, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

Adds robust remote-attachment error handling to assemblies and participatory_processes importers: validates URLs, replaces existence checks with a remote_file_error flow, wraps downloads in rescue blocks, normalizes error messages via format_error, and adds attachment_title for display; translations and tests updated accordingly.

Changes

Cohort / File(s) Summary
Assemblies importer
decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb
Replaces remote_file_exists? with remote_file_error(url), wraps URI.open in begin/rescue, adds attachment_title and format_error, and updates attachment/image import warning flows.
Assemblies locales
decidim-assemblies/config/locales/en.yml
Updates hero/banner error messages format and adds attachment_error translation using "%{title}" and (%{error}) style.
Assemblies tests
decidim-assemblies/spec/serializers/.../assembly_importer_spec.rb, decidim-assemblies/spec/system/admin/admin_imports_assembly_spec.rb
Updates expectations to assert precise formatted error messages (e.g., “(404 Not Found)”, “(500 Internal Server Error)”) and adds attachment failure scenarios (404, 500, download error).
Participatory Processes importer
decidim-participatory_processes/app/serializers/decidim/participatory_processes/participatory_process_importer.rb
Mirrors assemblies changes: adds remote_file_error, attachment_title, format_error, wraps downloads, and uses formatted warnings for hero/group images and attachments.
Participatory Processes locales
decidim-participatory_processes/config/locales/en.yml
Adds attachment_error translation and normalizes hero_image_error to the new (%{error}) format.
Participatory Processes tests
decidim-participatory_processes/spec/serializers/.../participatory_process_importer_spec.rb, decidim-participatory_processes/spec/system/admin/admin_import_participatory_process_spec.rb
Updates tests to expect status-tagged error messages for images and adds attachment failure tests (404, 500, download error).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

module: core

Suggested reviewers

  • alecslupu

Poem

🐰 I nibble URLs with careful paws,
I catch the timeout, note the cause,
I name the file so you can see,
“(404 Not Found)” — I whisper gently.
Hoppity-hop, imports safer now! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title specifically describes the main change: adding warning messages for 404 attachment URLs during import, which aligns with the primary objective of handling missing attachments gracefully.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/import-spaces-404-attachments

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb (2)

147-165: Consider adding explicit timeouts to the HTTP connection.

Net::HTTP.new defaults are 60 seconds for open/read timeouts, but the connection has no explicit timeout set. If the remote server is slow to respond to the HEAD request, this will block the import worker for up to 120 seconds per attachment. Given that imports can contain many attachments, this could cause significant delays or thread starvation.

Proposed fix
         http_connection = Net::HTTP.new(url.host, url.port)
         http_connection.use_ssl = true if url.scheme == "https"
+        http_connection.open_timeout = 5
+        http_connection.read_timeout = 5
         http_connection.start do |http|

71-122: Significant code duplication with ParticipatoryProcessImporter.

The methods remote_file_error, attachment_title, format_error, and the core logic of import_folders_and_attachments are virtually identical between AssemblyImporter and ParticipatoryProcessImporter. This makes maintenance error-prone — any future bug fix or enhancement must be applied to both files.

Consider extracting these shared methods into a common concern (e.g., Decidim::Importers::RemoteFileConcern) that both importers include.

Also applies to: 147-202

decidim-participatory_processes/app/serializers/decidim/participatory_processes/participatory_process_importer.rb (1)

174-192: Same missing timeout concern as in AssemblyImporter.

This remote_file_error implementation is identical to the one in AssemblyImporter and has the same lack of explicit timeouts on the HTTP connection. See the comment on the assembly importer for details.

Proposed fix
         http_connection = Net::HTTP.new(url.host, url.port)
         http_connection.use_ssl = true if url.scheme == "https"
+        http_connection.open_timeout = 5
+        http_connection.read_timeout = 5
         http_connection.start do |http|
decidim-assemblies/spec/system/admin/admin_imports_assembly_spec.rb (1)

97-313: Significant test setup duplication across contexts.

The json_data / json_file / uploaded_file let-blocks and the before block pattern (fill_in form, attach file, click Import) are repeated verbatim across five contexts (lines 97, 150, 203, 258, 315). Consider extracting these into shared let declarations and a shared before block at a higher scope, with per-context overrides for the URL modifications and stubs.

This is entirely optional for test files where readability can be more important than DRYness.

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

github-actions[bot]
github-actions bot previously approved these changes Feb 11, 2026
@andreslucena andreslucena changed the title Show a warning message when the space images URL are 404 Show a warning message when the attachments URL are 404 Feb 11, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb`:
- Around line 87-96: The rescue block around URI.parse(url).open in the assembly
importer should also handle Errno::ECONNREFUSED to mirror the error handling in
import_hero_image and import_banner_image; update the rescue clause that
currently catches OpenURI::HTTPError, Errno::ENOENT, SocketError,
Net::OpenTimeout, Net::ReadTimeout to include Errno::ECONNREFUSED so
connection-refused errors are captured, add the same error variable (e) usage in
the I18n warning message, and ensure this change is applied in the method where
file_tmp is assigned (the URI.open block in the
AssemblyImporter/assembly_importer.rb).

In
`@decidim-participatory_processes/app/serializers/decidim/participatory_processes/participatory_process_importer.rb`:
- Around line 109-118: The rescue block that handles download errors in
ParticipatoryProcessImporter (the block using URI.parse(url).open) is missing
Errno::ECONNREFUSED and can crash on connection-refused; update that rescue
clause to also catch Errno::ECONNREFUSED (matching the other methods
import_hero_image and import_group_hero_image) and ensure the same warning is
pushed into `@warnings` using e.message so connection-refused errors are handled
gracefully.
🧹 Nitpick comments (1)
decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb (1)

71-121: Significant code duplication with ParticipatoryProcessImporter.

import_folders_and_attachments, remote_file_exists?, and attachment_title are identical (modulo @imported_assembly vs @imported_process and the I18n key namespace) across AssemblyImporter and ParticipatoryProcessImporter. Consider extracting shared attachment-import logic into a concern or the base Decidim::Importers::Importer class to reduce duplication and ensure future fixes apply to both modules.

Also applies to: 160-167

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

github-actions[bot]
github-actions bot previously approved these changes Feb 12, 2026
coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 12, 2026
@andreslucena
Copy link
Copy Markdown
Member Author

This is ready for the review @alecslupu

Copy link
Copy Markdown
Contributor

@alecslupu alecslupu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - Mergng with qlty pipeline error

Image

@alecslupu alecslupu merged commit b93e2db into develop Feb 15, 2026
48 of 49 checks passed
@alecslupu alecslupu deleted the fix/import-spaces-404-attachments branch February 15, 2026 16:55
@alecslupu alecslupu added release: v0.30 Issues or PRs that need to be tackled for v0.30 release: v0.31 Issues or PRs that need to be tackled for v0.31 labels Feb 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

module: assemblies module: participatory processes release: v0.30 Issues or PRs that need to be tackled for v0.30 release: v0.31 Issues or PRs that need to be tackled for v0.31 type: fix PRs that implement a fix for a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants