-
Notifications
You must be signed in to change notification settings - Fork 2k
importsource: Catch importer crash when skipping; Fix original changelog entry; Add new tests #6203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- Catching a bare AssertionError here risks hiding unrelated bugs in imported_items; consider guarding this logic based on task state (e.g., task choice/skip status) or checking for the presence of imported items instead of relying on the assertion.
- Swallowing the AssertionError silently makes debugging harder if this path is hit unexpectedly; it would be helpful to at least log a debug message when the exception is caught so that it’s visible during troubleshooting.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Catching a bare AssertionError here risks hiding unrelated bugs in imported_items; consider guarding this logic based on task state (e.g., task choice/skip status) or checking for the presence of imported items instead of relying on the assertion.
- Swallowing the AssertionError silently makes debugging harder if this path is hit unexpectedly; it would be helpful to at least log a debug message when the exception is caught so that it’s visible during troubleshooting.
## Individual Comments
### Comment 1
<location> `beetsplug/importsource.py:42-47` </location>
<code_context>
- for item in task.imported_items():
- if "mb_albumid" in item:
- self.stop_suggestions_for_albums.add(item.mb_albumid)
+ try:
+ for item in task.imported_items():
+ if "mb_albumid" in item:
+ self.stop_suggestions_for_albums.add(item.mb_albumid)
+ except AssertionError:
+ # No imported items - nothing to do
+ pass
</code_context>
<issue_to_address>
**issue (bug_risk):** Catching AssertionError around the whole loop risks masking unrelated bugs.
Because the `try`/`except AssertionError` wraps the whole loop, any assertion triggered inside `task.imported_items()`, the membership check, or `add()` will be swallowed, not just the “no imported items” case. Please limit the `try` to the precise call that can raise for the empty-items condition (e.g. only `task.imported_items()`) or, if possible, detect “no imported items” without relying on catching `AssertionError`, so real programming errors are not suppressed.
</issue_to_address>
### Comment 2
<location> `beetsplug/importsource.py:46-48` </location>
<code_context>
+ for item in task.imported_items():
+ if "mb_albumid" in item:
+ self.stop_suggestions_for_albums.add(item.mb_albumid)
+ except AssertionError:
+ # No imported items - nothing to do
+ pass
def import_stage(self, _, task):
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Silently ignoring AssertionError may hinder debugging when unexpected conditions occur.
Catching `AssertionError` and doing nothing can mask genuine issues (e.g., unexpected `task`/`item` state). If the "no imported items" scenario is expected, consider narrowing the condition (e.g., checking for that case explicitly) or at least logging the exception at debug level so other assertion failures are visible.
Suggested implementation:
```python
def prevent_suggest_removal(self, session, task):
try:
for item in task.imported_items():
if "mb_albumid" in item:
self.stop_suggestions_for_albums.add(item.mb_albumid)
except AssertionError as exc:
# No imported items - nothing to do; log in case this masks a real issue.
log.debug(
"AssertionError while processing imported items for task %r: %s",
task,
exc,
exc_info=True,
)
```
If `log` is not already defined in `beetsplug/importsource.py`, you should:
1. Import the logging facility used by other beets plugins (for example, `from beets import logging`).
2. Initialize a module-level logger consistent with the rest of the codebase, e.g. `log = logging.getLogger(__name__)` or whatever convention other plugins in this project follow.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a crash in the importsource plugin when the user selects "skip" during import, which previously caused an AssertionError when task.imported_items() was called with an unsupported action.
Key Changes:
- Added try-except block around
task.imported_items()call inprevent_suggest_removalmethod to catch the AssertionError when tasks are skipped
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #6203 +/- ##
==========================================
- Coverage 68.36% 68.20% -0.17%
==========================================
Files 138 138
Lines 18773 18775 +2
Branches 3172 3173 +1
==========================================
- Hits 12834 12805 -29
- Misses 5263 5296 +33
+ Partials 676 674 -2
🚀 New features to boost your workflow:
|
|
I'm sure this is not the right way to fix this. Some eyes here @semohr or @snejus. Here we assert False, I suppose because this should never happen right? Lines 241 to 254 in 2bd77b9
|
|
Personally, I don't think we should have any I think we should either raise a dedicated exception with debugging details so we can identify which assumption is false, or else have that function return a |
|
@JOJ0 Do you have the full trace-back here? How do we even run into this? This is a quite old part of the codebase, how was this never an issue beforehand?
I agree fully here but I would like to figure out how and why we are now running into this issue now. We did not run into this for the previous 12 years afaik. (Empty list or none makes sense in my opinion) |
Sure. Here it is: |
|
There might be some design-flaws that slipped through my initial review of this plugin. One thing is that the listener here is of no use if the configuration of the plugin does not want to use that feature anyway: But still if we'd prevent registering the listener when not configured, it does not cure the problem that Should I try to include an "empty list or none fix" as you both suggested within this PR? |
|
Have you seen #6211? Would that approach also fully fix this issue? |
Yes definitely. Closed that one already. It's definitely correct to simply "not do prevent suggest stuff" if skip is chosen anyway. But I thought we wanted to maybe change the assert false to allow empty list/none in the importer code? Or better not and leave it as is? |
4f95a2f to
2b902fa
Compare
|
I applied the mentioned fix and rebased. Remains to be decided if we want to change things in the importer's |
7b8e4f0 to
b5ffb8d
Compare
b015fdb to
1e6a6ba
Compare
- Fix position (wrong release) - Elaborate wording
1e6a6ba to
9ffae4b
Compare
For now I would like to move on with getting this crash fixed and want to make the call here: Let's not touch the importer logic for now and move that decision to another time. Fixing this crash is my priority. See my updated PR description bulletpoints. I fixed the original changelog and added two IMO essential test cases. I'd like to request a final look here @semohr @Serene-Arc Thanks! |
semohr
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like a good way forward to me!
|
Thanks! |
Prevents a crash when "skip" is selected in the importer and
task.imported_items()runs into a condition branch that supposedly should never be reached:task.imported_items()is not required anyway, the fix here is to exit early from the function that calls it.To Do
Documentation.