From ec6918a790d021cbe78ca5f7d411ffdf8b11965d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 11 Nov 2023 12:22:11 +0530 Subject: [PATCH] Fix #2043248 [Embed metadata spawns infinite error popups](https://bugs.launchpad.net/calibre/+bug/2043248) --- src/calibre/db/cache.py | 21 ++++++++++++++++++++- src/calibre/gui2/actions/embed.py | 7 ++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 062b19237b..4c57102ecd 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -2902,7 +2902,26 @@ class Cache: except: continue if name and path: - new_size = self.backend.apply_to_format(book_id, path, name, fmt, partial(doit, fmt, mi)) + try: + new_size = self.backend.apply_to_format(book_id, path, name, fmt, partial(doit, fmt, mi)) + except Exception as e: + if report_error is not None: + tb = traceback.format_exc() + if iswindows and isinstance(e, PermissionError) and e.filename and isinstance(e.filename, str): + from calibre_extensions import winutil + try: + p = winutil.get_processes_using_files(e.filename) + except OSError: + pass + else: + path_map = {x['path']: x for x in p} + tb = _('Could not open the file: "{}". It is already opened in the following programs:').format(e.filename) + for path, x in path_map.items(): + tb += '\n' + f'{x["app_name"]}: {path}' + report_error(mi, fmt, tb) + new_size = None + else: + raise if new_size is not None: self.format_metadata_cache[book_id].get(fmt, {})['size'] = new_size max_size = self.fields['formats'].table.update_fmt(book_id, fmt, name, new_size, self.backend) diff --git a/src/calibre/gui2/actions/embed.py b/src/calibre/gui2/actions/embed.py index 83beb2569c..1f5b01f467 100644 --- a/src/calibre/gui2/actions/embed.py +++ b/src/calibre/gui2/actions/embed.py @@ -124,5 +124,10 @@ class EmbedAction(InterfaceAction): def report_error(mi, fmt, tb): mi.book_id = book_id errors.append((mi, fmt, tb)) - db.embed_metadata((book_id,), only_fmts=only_fmts, report_error=report_error) + try: + db.embed_metadata((book_id,), only_fmts=only_fmts, report_error=report_error) + except Exception: + import traceback + mi = db.get_metadata(book_id) + report_error(mi, '', traceback.format_exc()) self.job_data = (i + 1, book_ids, pd, only_fmts, errors)