[output] add 'Logger.traceback()' helper

This commit is contained in:
Mike Fährmann
2025-10-14 18:44:29 +02:00
parent 9d054ad18d
commit 8c62be343e
15 changed files with 33 additions and 27 deletions

View File

@@ -95,7 +95,7 @@ class HttpDownloader(DownloaderBase):
except Exception as exc: except Exception as exc:
if self.downloading: if self.downloading:
output.stderr_write("\n") output.stderr_write("\n")
self.log.debug("", exc_info=exc) self.log.traceback(exc)
raise raise
finally: finally:
# remove file from incomplete downloads # remove file from incomplete downloads

View File

@@ -49,7 +49,7 @@ class YoutubeDLDownloader(DownloaderBase):
except (ImportError, SyntaxError) as exc: except (ImportError, SyntaxError) as exc:
self.log.error("Cannot import module '%s'", self.log.error("Cannot import module '%s'",
getattr(exc, "name", "")) getattr(exc, "name", ""))
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.download = lambda u, p: False self.download = lambda u, p: False
return False return False
@@ -91,7 +91,7 @@ class YoutubeDLDownloader(DownloaderBase):
else: else:
info_dict = self._extract_info(ytdl_instance, url) info_dict = self._extract_info(ytdl_instance, url)
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.log.warning("%s: %s", exc.__class__.__name__, exc) self.log.warning("%s: %s", exc.__class__.__name__, exc)
if not info_dict: if not info_dict:
@@ -164,7 +164,7 @@ class YoutubeDLDownloader(DownloaderBase):
try: try:
ytdl_instance.process_info(info_dict) ytdl_instance.process_info(info_dict)
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
return False return False
pathfmt.temppath = info_dict.get("filepath") or info_dict["_filename"] pathfmt.temppath = info_dict.get("filepath") or info_dict["_filename"]
@@ -188,7 +188,7 @@ class YoutubeDLDownloader(DownloaderBase):
ytdl_instance.process_info(entry) ytdl_instance.process_info(entry)
status = True status = True
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.log.error("%s: %s", exc.__class__.__name__, exc) self.log.error("%s: %s", exc.__class__.__name__, exc)
return status return status

View File

@@ -211,7 +211,7 @@ class CivitaiExtractor(Extractor):
try: try:
return self.api.image_generationdata(image["id"]) return self.api.image_generationdata(image["id"])
except Exception as exc: except Exception as exc:
return self.log.debug("", exc_info=exc) return self.log.traceback(exc)
def _extract_meta_post(self, image): def _extract_meta_post(self, image):
try: try:
@@ -220,7 +220,7 @@ class CivitaiExtractor(Extractor):
post["publishedAt"], "%Y-%m-%dT%H:%M:%S.%fZ") post["publishedAt"], "%Y-%m-%dT%H:%M:%S.%fZ")
return post return post
except Exception as exc: 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): def _extract_meta_version(self, item, is_post=True):
try: try:
@@ -228,7 +228,7 @@ class CivitaiExtractor(Extractor):
version = self.api.model_version(version_id).copy() version = self.api.model_version(version_id).copy()
return version.pop("model", None), version return version.pop("model", None), version
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
return None, None return None, None
def _extract_version_id(self, item, is_post=True): def _extract_version_id(self, item, is_post=True):

View File

@@ -404,7 +404,7 @@ class DeviantartExtractor(Extractor):
try: try:
return self._tiptap_to_html(markup) return self._tiptap_to_html(markup)
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.log.error("%s: '%s: %s'", deviation["index"], self.log.error("%s: '%s: %s'", deviation["index"],
exc.__class__.__name__, exc) exc.__class__.__name__, exc)

View File

@@ -79,7 +79,7 @@ class FanslyExtractor(Extractor):
try: try:
self._extract_attachment(files, post, attachment) self._extract_attachment(files, post, attachment)
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.log.error( self.log.error(
"%s/%s, Failed to extract media (%s: %s)", "%s/%s, Failed to extract media (%s: %s)",
post["id"], attachment.get("id"), post["id"], attachment.get("id"),

View File

@@ -38,7 +38,7 @@ class FlickrExtractor(Extractor):
self.log.warning( self.log.warning(
"Skipping photo %s (%s: %s)", "Skipping photo %s (%s: %s)",
photo["id"], exc.__class__.__name__, exc) photo["id"], exc.__class__.__name__, exc)
self.log.debug("", exc_info=exc) self.log.traceback(exc)
else: else:
photo.update(data) photo.update(data)
url = self._file_url(photo) url = self._file_url(photo)

View File

@@ -68,7 +68,7 @@ class IssuuUserExtractor(IssuuBase, Extractor):
data = text.extr(html, '\\"docs\\":', '}]\\n"]') data = text.extr(html, '\\"docs\\":', '}]\\n"]')
docs = util.json_loads(data.replace('\\"', '"')) docs = util.json_loads(data.replace('\\"', '"'))
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
return return
for publication in docs: for publication in docs:

View File

@@ -58,7 +58,7 @@ class NewgroundsExtractor(Extractor):
post = self.extract_post(post_url) post = self.extract_post(post_url)
url = post.get("url") url = post.get("url")
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
url = None url = None
if url: if url:

View File

@@ -46,7 +46,7 @@ class PinterestExtractor(Extractor):
try: try:
files = self._extract_files(pin) files = self._extract_files(pin)
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.log.warning( self.log.warning(
"%s: Error when extracting download URLs (%s: %s)", "%s: Error when extracting download URLs (%s: %s)",
pin.get("id"), exc.__class__.__name__, exc) pin.get("id"), exc.__class__.__name__, exc)

View File

@@ -149,7 +149,7 @@ class PixivExtractor(Extractor):
self._extract_ajax(work, body) self._extract_ajax(work, body)
return self._extract_ugoira(work, url) return self._extract_ugoira(work, url)
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.log.warning( self.log.warning(
"%s: Unable to extract Ugoira URL. Provide " "%s: Unable to extract Ugoira URL. Provide "
"logged-in cookies to access it", work["id"]) "logged-in cookies to access it", work["id"])
@@ -453,7 +453,7 @@ class PixivArtworksExtractor(PixivExtractor):
ajax_ids.extend(map(int, body["manga"])) ajax_ids.extend(map(int, body["manga"]))
ajax_ids.sort() ajax_ids.sort()
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.log.warning("u%s: Failed to collect artwork IDs " self.log.warning("u%s: Failed to collect artwork IDs "
"using AJAX API", self.user_id) "using AJAX API", self.user_id)
else: else:

View File

@@ -214,7 +214,7 @@ class TiktokUserExtractor(TiktokExtractor):
except (ImportError, SyntaxError) as exc: except (ImportError, SyntaxError) as exc:
self.log.error("Cannot import module '%s'", self.log.error("Cannot import module '%s'",
getattr(exc, "name", "")) getattr(exc, "name", ""))
self.log.debug("", exc_info=exc) self.log.traceback(exc)
raise exception.ExtractionError("yt-dlp or youtube-dl is required " raise exception.ExtractionError("yt-dlp or youtube-dl is required "
"for this feature!") "for this feature!")

View File

@@ -146,7 +146,7 @@ class TwitterExtractor(Extractor):
self._extract_media( self._extract_media(
data, data["extended_entities"]["media"], files) data, data["extended_entities"]["media"], files)
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.log.warning( self.log.warning(
"%s: Error while extracting media files (%s: %s)", "%s: Error while extracting media files (%s: %s)",
data["id_str"], exc.__class__.__name__, exc) data["id_str"], exc.__class__.__name__, exc)
@@ -155,7 +155,7 @@ class TwitterExtractor(Extractor):
try: try:
self._extract_card(tweet, files) self._extract_card(tweet, files)
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.log.warning( self.log.warning(
"%s: Error while extracting Card files (%s: %s)", "%s: Error while extracting Card files (%s: %s)",
data["id_str"], exc.__class__.__name__, exc) data["id_str"], exc.__class__.__name__, exc)
@@ -164,7 +164,7 @@ class TwitterExtractor(Extractor):
try: try:
self._extract_twitpic(data, files) self._extract_twitpic(data, files)
except Exception as exc: except Exception as exc:
self.log.debug("", exc_info=exc) self.log.traceback(exc)
self.log.warning( self.log.warning(
"%s: Error while extracting TwitPic files (%s: %s)", "%s: Error while extracting TwitPic files (%s: %s)",
data["id_str"], exc.__class__.__name__, exc) data["id_str"], exc.__class__.__name__, exc)

View File

@@ -157,16 +157,17 @@ class Job():
raise raise
pass pass
except exception.AbortExtraction as exc: except exception.AbortExtraction as exc:
log.traceback(exc)
log.error(exc.message) log.error(exc.message)
self.status |= exc.code self.status |= exc.code
except (exception.TerminateExtraction, exception.RestartExtraction): except (exception.TerminateExtraction, exception.RestartExtraction):
raise raise
except exception.GalleryDLException as exc: except exception.GalleryDLException as exc:
log.error("%s: %s", exc.__class__.__name__, exc) log.error("%s: %s", exc.__class__.__name__, exc)
log.debug("", exc_info=exc) log.traceback(exc)
self.status |= exc.code self.status |= exc.code
except OSError as exc: except OSError as exc:
log.debug("", exc_info=exc) log.traceback(exc)
if (name := exc.__class__.__name__) == "JSONDecodeError": if (name := exc.__class__.__name__) == "JSONDecodeError":
log.error("Failed to parse JSON data: %s: %s", name, exc) log.error("Failed to parse JSON data: %s: %s", name, exc)
self.status |= 1 self.status |= 1
@@ -179,7 +180,7 @@ class Job():
"copy its output and report this issue on " "copy its output and report this issue on "
"https://github.com/mikf/gallery-dl/issues ."), "https://github.com/mikf/gallery-dl/issues ."),
exc.__class__.__name__, exc) exc.__class__.__name__, exc)
log.debug("", exc_info=exc) log.traceback(exc)
self.status |= 1 self.status |= 1
except BaseException: except BaseException:
self.status |= 1 self.status |= 1
@@ -690,9 +691,9 @@ class DownloadJob(Job):
try: try:
pp_obj = pp_cls(self, pp_dict) pp_obj = pp_cls(self, pp_dict)
except Exception as exc: except Exception as exc:
pp_log.traceback(exc)
pp_log.error("'%s' initialization failed: %s: %s", pp_log.error("'%s' initialization failed: %s: %s",
name, exc.__class__.__name__, exc) name, exc.__class__.__name__, exc)
pp_log.debug("", exc_info=exc)
else: else:
pp_list.append(pp_obj) pp_list.append(pp_obj)

View File

@@ -89,6 +89,11 @@ class LoggerAdapter():
self.logger = logger self.logger = logger
self.extra = job._logger_extra 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): def debug(self, msg, *args, **kwargs):
if self.logger.isEnabledFor(logging.DEBUG): if self.logger.isEnabledFor(logging.DEBUG):
kwargs["extra"] = self.extra kwargs["extra"] = self.extra

View File

@@ -151,7 +151,7 @@ class UgoiraPP(PostProcessor):
"%s: Unable to extract frames from %s (%s: %s)", "%s: Unable to extract frames from %s (%s: %s)",
pathfmt.kwdict.get("id"), pathfmt.filename, pathfmt.kwdict.get("id"), pathfmt.filename,
exc.__class__.__name__, exc) exc.__class__.__name__, exc)
return self.log.debug("", exc_info=exc) return self.log.traceback(exc)
if self.convert(pathfmt, tempdir): if self.convert(pathfmt, tempdir):
if self.delete: if self.delete:
@@ -227,12 +227,12 @@ class UgoiraPP(PostProcessor):
output.stderr_write("\n") output.stderr_write("\n")
self.log.error("Unable to invoke FFmpeg (%s: %s)", self.log.error("Unable to invoke FFmpeg (%s: %s)",
exc.__class__.__name__, exc) exc.__class__.__name__, exc)
self.log.debug("", exc_info=exc) self.log.traceback(exc)
pathfmt.realpath = pathfmt.temppath pathfmt.realpath = pathfmt.temppath
except Exception as exc: except Exception as exc:
output.stderr_write("\n") output.stderr_write("\n")
self.log.error("%s: %s", exc.__class__.__name__, exc) self.log.error("%s: %s", exc.__class__.__name__, exc)
self.log.debug("", exc_info=exc) self.log.traceback(exc)
pathfmt.realpath = pathfmt.temppath pathfmt.realpath = pathfmt.temppath
else: else:
if self.mtime: if self.mtime: