Fix importfeeds to continue on symlink creation failures#6765
Fix importfeeds to continue on symlink creation failures#6765sammydynamo-dev wants to merge 7 commits into
Conversation
When `formats` includes `link`, importfeeds creates a symlink per imported item. A failed symlink (lacking privilege on Windows, a read-only directory, or a filesystem without symlink support) raised beets.util.FilesystemError out of the import pipeline and aborted the whole `beet import` run, even though the tracks were already imported. Catch FilesystemError around the link() call, log a per-item warning, and continue with the remaining items. Add regression tests for the warn-and-continue behaviour, that only FilesystemError is caught, and that a successful link still creates the symlink. Fixes beetbox#840. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #6765 +/- ##
==========================================
+ Coverage 74.78% 74.81% +0.03%
==========================================
Files 163 163
Lines 20966 20969 +3
Branches 3302 3302
==========================================
+ Hits 15680 15689 +9
+ Misses 4529 4523 -6
Partials 757 757
🚀 New features to boost your workflow:
|
|
Hi @snejus 👋 — this is my first contribution to beets. This PR (#6765) fixes #840: when It includes five regression tests and a changelog entry, and the full test suite |
Description
Fixes #840.
When
importfeedsis configured withformats: link, it creates a symlink for each imported track. If that symlink can't be created — on Windows without the privilege to make symlinks (the original report), but also on any OS when the destination directory isn't writable or the filesystem doesn't support symlinks —beets.util.link()raisesFilesystemError. That exception wasn't caught, so it propagated out of the import pipeline and aborted the entirebeet importrun, even though the tracks had already been imported into the library.This wraps the
link()call inImportFeedsPlugin._record_items()intry/except FilesystemError, logs a per-item warning, and continues with the remaining items — so a failed symlink is skipped rather than fatal. This is the "catch and skip" behaviour suggested in the issue thread. It catchesFilesystemError(notOSError, whichutil.link()wraps) and mirrors the existing handling inbeetsplug/playlist.pyand the fetchart fix (#6193).Adds five regression tests (warn-and-continue, that remaining items are still linked, that only
FilesystemErroris caught, and that a successful link still creates the symlink). Also verified manually: with a read-only feeds directory,beet importnow finishes with a warning (exit0) instead of aborting (exit1), and the track is still imported.To Do
Documentation(bugfix; no user-facing flag or config changed)