From 8c62be343eb8a3b7e3bebdc7566b60c87e4e3666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20F=C3=A4hrmann?= Date: Tue, 14 Oct 2025 18:44:29 +0200 Subject: [PATCH] [output] add 'Logger.traceback()' helper --- gallery_dl/downloader/http.py | 2 +- gallery_dl/downloader/ytdl.py | 8 ++++---- gallery_dl/extractor/civitai.py | 6 +++--- gallery_dl/extractor/deviantart.py | 2 +- gallery_dl/extractor/fansly.py | 2 +- gallery_dl/extractor/flickr.py | 2 +- gallery_dl/extractor/issuu.py | 2 +- gallery_dl/extractor/newgrounds.py | 2 +- gallery_dl/extractor/pinterest.py | 2 +- gallery_dl/extractor/pixiv.py | 4 ++-- gallery_dl/extractor/tiktok.py | 2 +- gallery_dl/extractor/twitter.py | 6 +++--- gallery_dl/job.py | 9 +++++---- gallery_dl/output.py | 5 +++++ gallery_dl/postprocessor/ugoira.py | 6 +++--- 15 files changed, 33 insertions(+), 27 deletions(-) diff --git a/gallery_dl/downloader/http.py b/gallery_dl/downloader/http.py index 248bf70f..813e0fc8 100644 --- a/gallery_dl/downloader/http.py +++ b/gallery_dl/downloader/http.py @@ -95,7 +95,7 @@ class HttpDownloader(DownloaderBase): except Exception as exc: if self.downloading: output.stderr_write("\n") - self.log.debug("", exc_info=exc) + self.log.traceback(exc) raise finally: # remove file from incomplete downloads diff --git a/gallery_dl/downloader/ytdl.py b/gallery_dl/downloader/ytdl.py index a56a6be7..59d299ca 100644 --- a/gallery_dl/downloader/ytdl.py +++ b/gallery_dl/downloader/ytdl.py @@ -49,7 +49,7 @@ class YoutubeDLDownloader(DownloaderBase): except (ImportError, SyntaxError) as exc: self.log.error("Cannot import module '%s'", getattr(exc, "name", "")) - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.download = lambda u, p: False return False @@ -91,7 +91,7 @@ class YoutubeDLDownloader(DownloaderBase): else: info_dict = self._extract_info(ytdl_instance, url) except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.log.warning("%s: %s", exc.__class__.__name__, exc) if not info_dict: @@ -164,7 +164,7 @@ class YoutubeDLDownloader(DownloaderBase): try: ytdl_instance.process_info(info_dict) except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) return False pathfmt.temppath = info_dict.get("filepath") or info_dict["_filename"] @@ -188,7 +188,7 @@ class YoutubeDLDownloader(DownloaderBase): ytdl_instance.process_info(entry) status = True except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.log.error("%s: %s", exc.__class__.__name__, exc) return status diff --git a/gallery_dl/extractor/civitai.py b/gallery_dl/extractor/civitai.py index 26ee3fdd..c546e5d2 100644 --- a/gallery_dl/extractor/civitai.py +++ b/gallery_dl/extractor/civitai.py @@ -211,7 +211,7 @@ class CivitaiExtractor(Extractor): try: return self.api.image_generationdata(image["id"]) except Exception as exc: - return self.log.debug("", exc_info=exc) + return self.log.traceback(exc) def _extract_meta_post(self, image): try: @@ -220,7 +220,7 @@ class CivitaiExtractor(Extractor): post["publishedAt"], "%Y-%m-%dT%H:%M:%S.%fZ") return post except Exception as exc: - return self.log.debug("", exc_info=exc) + return self.log.traceback(exc) def _extract_meta_version(self, item, is_post=True): try: @@ -228,7 +228,7 @@ class CivitaiExtractor(Extractor): version = self.api.model_version(version_id).copy() return version.pop("model", None), version except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) return None, None def _extract_version_id(self, item, is_post=True): diff --git a/gallery_dl/extractor/deviantart.py b/gallery_dl/extractor/deviantart.py index 39690da2..0ca7520a 100644 --- a/gallery_dl/extractor/deviantart.py +++ b/gallery_dl/extractor/deviantart.py @@ -404,7 +404,7 @@ class DeviantartExtractor(Extractor): try: return self._tiptap_to_html(markup) except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.log.error("%s: '%s: %s'", deviation["index"], exc.__class__.__name__, exc) diff --git a/gallery_dl/extractor/fansly.py b/gallery_dl/extractor/fansly.py index 7138599e..a1ab2ce3 100644 --- a/gallery_dl/extractor/fansly.py +++ b/gallery_dl/extractor/fansly.py @@ -79,7 +79,7 @@ class FanslyExtractor(Extractor): try: self._extract_attachment(files, post, attachment) except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.log.error( "%s/%s, Failed to extract media (%s: %s)", post["id"], attachment.get("id"), diff --git a/gallery_dl/extractor/flickr.py b/gallery_dl/extractor/flickr.py index 35263a31..20d29984 100644 --- a/gallery_dl/extractor/flickr.py +++ b/gallery_dl/extractor/flickr.py @@ -38,7 +38,7 @@ class FlickrExtractor(Extractor): self.log.warning( "Skipping photo %s (%s: %s)", photo["id"], exc.__class__.__name__, exc) - self.log.debug("", exc_info=exc) + self.log.traceback(exc) else: photo.update(data) url = self._file_url(photo) diff --git a/gallery_dl/extractor/issuu.py b/gallery_dl/extractor/issuu.py index 06c5caa5..5828cfe9 100644 --- a/gallery_dl/extractor/issuu.py +++ b/gallery_dl/extractor/issuu.py @@ -68,7 +68,7 @@ class IssuuUserExtractor(IssuuBase, Extractor): data = text.extr(html, '\\"docs\\":', '}]\\n"]') docs = util.json_loads(data.replace('\\"', '"')) except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) return for publication in docs: diff --git a/gallery_dl/extractor/newgrounds.py b/gallery_dl/extractor/newgrounds.py index ffb4cadb..1161b7f1 100644 --- a/gallery_dl/extractor/newgrounds.py +++ b/gallery_dl/extractor/newgrounds.py @@ -58,7 +58,7 @@ class NewgroundsExtractor(Extractor): post = self.extract_post(post_url) url = post.get("url") except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) url = None if url: diff --git a/gallery_dl/extractor/pinterest.py b/gallery_dl/extractor/pinterest.py index ff771fba..a85b67d0 100644 --- a/gallery_dl/extractor/pinterest.py +++ b/gallery_dl/extractor/pinterest.py @@ -46,7 +46,7 @@ class PinterestExtractor(Extractor): try: files = self._extract_files(pin) except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.log.warning( "%s: Error when extracting download URLs (%s: %s)", pin.get("id"), exc.__class__.__name__, exc) diff --git a/gallery_dl/extractor/pixiv.py b/gallery_dl/extractor/pixiv.py index 5b4a95a9..586a4de6 100644 --- a/gallery_dl/extractor/pixiv.py +++ b/gallery_dl/extractor/pixiv.py @@ -149,7 +149,7 @@ class PixivExtractor(Extractor): self._extract_ajax(work, body) return self._extract_ugoira(work, url) except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.log.warning( "%s: Unable to extract Ugoira URL. Provide " "logged-in cookies to access it", work["id"]) @@ -453,7 +453,7 @@ class PixivArtworksExtractor(PixivExtractor): ajax_ids.extend(map(int, body["manga"])) ajax_ids.sort() except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.log.warning("u%s: Failed to collect artwork IDs " "using AJAX API", self.user_id) else: diff --git a/gallery_dl/extractor/tiktok.py b/gallery_dl/extractor/tiktok.py index f4508066..3ca72c51 100644 --- a/gallery_dl/extractor/tiktok.py +++ b/gallery_dl/extractor/tiktok.py @@ -214,7 +214,7 @@ class TiktokUserExtractor(TiktokExtractor): except (ImportError, SyntaxError) as exc: self.log.error("Cannot import module '%s'", getattr(exc, "name", "")) - self.log.debug("", exc_info=exc) + self.log.traceback(exc) raise exception.ExtractionError("yt-dlp or youtube-dl is required " "for this feature!") diff --git a/gallery_dl/extractor/twitter.py b/gallery_dl/extractor/twitter.py index bf125a60..142a5f9d 100644 --- a/gallery_dl/extractor/twitter.py +++ b/gallery_dl/extractor/twitter.py @@ -146,7 +146,7 @@ class TwitterExtractor(Extractor): self._extract_media( data, data["extended_entities"]["media"], files) except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.log.warning( "%s: Error while extracting media files (%s: %s)", data["id_str"], exc.__class__.__name__, exc) @@ -155,7 +155,7 @@ class TwitterExtractor(Extractor): try: self._extract_card(tweet, files) except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.log.warning( "%s: Error while extracting Card files (%s: %s)", data["id_str"], exc.__class__.__name__, exc) @@ -164,7 +164,7 @@ class TwitterExtractor(Extractor): try: self._extract_twitpic(data, files) except Exception as exc: - self.log.debug("", exc_info=exc) + self.log.traceback(exc) self.log.warning( "%s: Error while extracting TwitPic files (%s: %s)", data["id_str"], exc.__class__.__name__, exc) diff --git a/gallery_dl/job.py b/gallery_dl/job.py index 2959627b..841608e3 100644 --- a/gallery_dl/job.py +++ b/gallery_dl/job.py @@ -157,16 +157,17 @@ class Job(): raise pass except exception.AbortExtraction as exc: + log.traceback(exc) log.error(exc.message) self.status |= exc.code except (exception.TerminateExtraction, exception.RestartExtraction): raise except exception.GalleryDLException as exc: log.error("%s: %s", exc.__class__.__name__, exc) - log.debug("", exc_info=exc) + log.traceback(exc) self.status |= exc.code except OSError as exc: - log.debug("", exc_info=exc) + log.traceback(exc) if (name := exc.__class__.__name__) == "JSONDecodeError": log.error("Failed to parse JSON data: %s: %s", name, exc) self.status |= 1 @@ -179,7 +180,7 @@ class Job(): "copy its output and report this issue on " "https://github.com/mikf/gallery-dl/issues ."), exc.__class__.__name__, exc) - log.debug("", exc_info=exc) + log.traceback(exc) self.status |= 1 except BaseException: self.status |= 1 @@ -690,9 +691,9 @@ class DownloadJob(Job): try: pp_obj = pp_cls(self, pp_dict) except Exception as exc: + pp_log.traceback(exc) pp_log.error("'%s' initialization failed: %s: %s", name, exc.__class__.__name__, exc) - pp_log.debug("", exc_info=exc) else: pp_list.append(pp_obj) diff --git a/gallery_dl/output.py b/gallery_dl/output.py index 9e0888bd..3be23e58 100644 --- a/gallery_dl/output.py +++ b/gallery_dl/output.py @@ -89,6 +89,11 @@ class LoggerAdapter(): self.logger = logger self.extra = job._logger_extra + def traceback(self, exc): + if self.logger.isEnabledFor(logging.DEBUG): + self.logger._log( + logging.DEBUG, "", None, exc_info=exc, extra=self.extra) + def debug(self, msg, *args, **kwargs): if self.logger.isEnabledFor(logging.DEBUG): kwargs["extra"] = self.extra diff --git a/gallery_dl/postprocessor/ugoira.py b/gallery_dl/postprocessor/ugoira.py index 1a55e22c..3813faec 100644 --- a/gallery_dl/postprocessor/ugoira.py +++ b/gallery_dl/postprocessor/ugoira.py @@ -151,7 +151,7 @@ class UgoiraPP(PostProcessor): "%s: Unable to extract frames from %s (%s: %s)", pathfmt.kwdict.get("id"), pathfmt.filename, exc.__class__.__name__, exc) - return self.log.debug("", exc_info=exc) + return self.log.traceback(exc) if self.convert(pathfmt, tempdir): if self.delete: @@ -227,12 +227,12 @@ class UgoiraPP(PostProcessor): output.stderr_write("\n") self.log.error("Unable to invoke FFmpeg (%s: %s)", exc.__class__.__name__, exc) - self.log.debug("", exc_info=exc) + self.log.traceback(exc) pathfmt.realpath = pathfmt.temppath except Exception as exc: output.stderr_write("\n") self.log.error("%s: %s", exc.__class__.__name__, exc) - self.log.debug("", exc_info=exc) + self.log.traceback(exc) pathfmt.realpath = pathfmt.temppath else: if self.mtime: