Update all references in core, plugins, and tests to import UserError
from the new location. This centralizes exception handling and improves
code organization.
Move search orchestration into SearchApiMetadataSourcePlugin.
Migrate Deezer, Spotify, and Discogs to provider hooks.
Keep query handling, logging, and limits centralized.
## Description
This PR adds gracefully handling requests error in teh Deezer plugin. Right now, it errors out when it receives error:
```bash
Traceback (most recent call last):
File "/home/arsaboo/.local/bin/beet", line 8, in <module>
sys.exit(main())
^^^^^^
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/ui/__init__.py", line 1865, in main
_raw_main(args)
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/ui/__init__.py", line 1852, in _raw_main
subcommand.func(lib, suboptions, subargs)
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/ui/commands.py", line 1395, in import_func
import_files(lib, paths, query)
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/ui/commands.py", line 1326, in import_files
session.run()
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/importer.py", line 360, in run
pl.run_parallel(QUEUE_SIZE)
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/util/pipeline.py", line 447, in run_parallel
raise exc_info[1].with_traceback(exc_info[2])
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/util/pipeline.py", line 312, in run
out = self.coro.send(msg)
^^^^^^^^^^^^^^^^^^^
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/util/pipeline.py", line 195, in coro
func(*(args + (task,)))
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/importer.py", line 1497, in lookup_candidates
task.lookup_candidates()
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/importer.py", line 688, in lookup_candidates
artist, album, prop = autotag.tag_album(
^^^^^^^^^^^^^^^^^^
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/autotag/match.py", line 548, in tag_album
for matched_candidate in hooks.album_candidates(
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/plugins.py", line 593, in decorated
for v in generator(*args, **kwargs):
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/autotag/hooks.py", line 759, in album_candidates
yield from plugins.candidates(items, artist, album, va_likely, extra_tags)
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/plugins.py", line 390, in candidates
yield from plugin.candidates(
^^^^^^^^^^^^^^^^^^
File "/home/arsaboo/.local/lib/python3.12/site-packages/beets/plugins.py", line 772, in candidates
results = self._search_api(query_type="album", filters=query_filters)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/arsaboo/.local/lib/python3.12/site-packages/beetsplug/deezer.py", line 282, in _search_api
response.raise_for_status()
File "/home/arsaboo/.local/lib/python3.12/site-packages/requests/models.py", line 1024, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://api.deezer.com/search/album?q=album%3A%22Y+Hate+%3F%22+artist%3A%22Parmish+Verma%22
```
## To Do
- [ ] Documentation. (If you've added a new command-line flag, for example, find the appropriate page under `docs/` to describe it.)
- [x] Changelog. (Add an entry to `docs/changelog.rst` to the bottom of one of the lists near the top of the document.)
- [ ] Tests. (Very much encouraged but not strictly required.)