overhaul exception stuff

This commit is contained in:
Mike Fährmann
2019-10-27 23:05:00 +01:00
parent 109718a5e3
commit c887493a80
3 changed files with 75 additions and 60 deletions

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2015-2018 Mike Fährmann # Copyright 2015-2019 Mike Fährmann
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as # it under the terms of the GNU General Public License version 2 as
@@ -17,63 +17,90 @@ Exception
| +-- AuthorizationError | +-- AuthorizationError
| +-- NotFoundError | +-- NotFoundError
| +-- HttpError | +-- HttpError
+-- DownloadError
| +-- DownloadComplete
| +-- DownloadRetry
+-- NoExtractorError
+-- FormatError +-- FormatError
| +-- FilenameFormatError
| +-- DirectoryFormatError
+-- FilterError +-- FilterError
+-- NoExtractorError
+-- StopExtraction +-- StopExtraction
""" """
class GalleryDLException(Exception): class GalleryDLException(Exception):
"""Base class for GalleryDL exceptions""" """Base class for GalleryDL exceptions"""
default = None
msgfmt = None
code = 1
def __init__(self, message=None):
if not message:
message = self.default
elif isinstance(message, Exception):
message = "{}: {}".format(message.__class__.__name__, message)
if self.msgfmt:
message = self.msgfmt.format(message)
Exception.__init__(self, message)
class ExtractionError(GalleryDLException): class ExtractionError(GalleryDLException):
"""Base class for exceptions during information extraction""" """Base class for exceptions during information extraction"""
class HttpError(ExtractionError):
"""HTTP request during data extraction failed"""
default = "HTTP request failed"
code = 4
class NotFoundError(ExtractionError):
"""Requested resource (gallery/image) could not be found"""
msgfmt = "Requested {} could not be found"
default = "resource (gallery/image)"
code = 8
class AuthenticationError(ExtractionError): class AuthenticationError(ExtractionError):
"""Invalid or missing login information""" """Invalid or missing login credentials"""
default = "Invalid or missing login credentials"
code = 16
class AuthorizationError(ExtractionError): class AuthorizationError(ExtractionError):
"""Insufficient privileges to access a resource""" """Insufficient privileges to access a resource"""
default = "Insufficient privileges to access a resource"
code = 16
class NotFoundError(ExtractionError):
"""Requested resource (gallery/image) does not exist"""
class HttpError(ExtractionError):
"""HTTP request during extraction failed"""
class DownloadError(GalleryDLException):
"""Base class for exceptions during file downloads"""
class DownloadRetry(DownloadError):
"""Download attempt failed and should be retried"""
class DownloadComplete(DownloadError):
"""Output file of attempted download is already complete"""
class NoExtractorError(GalleryDLException):
"""No extractor can handle the given URL"""
class FormatError(GalleryDLException): class FormatError(GalleryDLException):
"""Error while building output path""" """Error while building output paths"""
code = 32
class FilenameFormatError(FormatError):
"""Error while building output filenames"""
msgfmt = "Applying filename format string failed ({})"
class DirectoryFormatError(FormatError):
"""Error while building output directory paths"""
msgfmt = "Applying directory format string failed ({})"
class FilterError(GalleryDLException): class FilterError(GalleryDLException):
"""Error while evaluating a filter expression""" """Error while evaluating a filter expression"""
msgfmt = "Evaluating filter expression failed ({})"
code = 32
class NoExtractorError(GalleryDLException):
"""No extractor can handle the given URL"""
code = 64
class StopExtraction(GalleryDLException): class StopExtraction(GalleryDLException):
"""Extraction should stop""" """Stop data extraction"""
def __init__(self, message=None):
GalleryDLException.__init__(self)
self.message = message
self.code = 1 if message else 0

View File

@@ -46,34 +46,18 @@ class Job():
log = self.extractor.log log = self.extractor.log
for msg in self.extractor: for msg in self.extractor:
self.dispatch(msg) self.dispatch(msg)
except exception.AuthenticationError as exc: except exception.StopExtraction as exc:
msg = str(exc) or "Please provide a valid username/password pair." if exc.message:
log.error("Authentication failed: %s", msg) log.error("%s", exc.message)
except exception.AuthorizationError: return exc.code
log.error("You do not have permission to access the resource " except exception.GalleryDLException as exc:
"at '%s'", self.extractor.url) log.error("%s: %s", exc.__class__.__name__, exc)
except exception.NotFoundError as exc: return exc.code
res = str(exc) or "resource (gallery/image/user)"
log.error("The %s at '%s' does not exist", res, self.extractor.url)
except exception.HttpError as exc:
err = exc.args[0]
if isinstance(err, Exception):
err = "{}: {}".format(err.__class__.__name__, err)
log.error("HTTP request failed: %s", err)
except exception.FormatError as exc:
err, obj = exc.args
log.error("Applying %s format string failed: %s: %s",
obj, err.__class__.__name__, err)
except exception.FilterError as exc:
err = exc.args[0]
log.error("Evaluating filter expression failed: %s: %s",
err.__class__.__name__, err)
except exception.StopExtraction:
pass
except OSError as exc: except OSError as exc:
log.error("Unable to download data: %s: %s", log.error("Unable to download data: %s: %s",
exc.__class__.__name__, exc) exc.__class__.__name__, exc)
log.debug("", exc_info=True) log.debug("", exc_info=True)
return 128
except Exception as exc: except Exception as exc:
log.error(("An unexpected error occurred: %s - %s. " log.error(("An unexpected error occurred: %s - %s. "
"Please run gallery-dl again with the --verbose flag, " "Please run gallery-dl again with the --verbose flag, "
@@ -81,6 +65,9 @@ class Job():
"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=True) log.debug("", exc_info=True)
return 1
else:
return 0
finally: finally:
self.handle_finalize() self.handle_finalize()
@@ -504,6 +491,7 @@ class DataJob(Job):
# dump to 'file' # dump to 'file'
util.dump_json(self.data, self.file, self.ascii, 2) util.dump_json(self.data, self.file, self.ascii, 2)
return 0
def handle_url(self, url, kwdict): def handle_url(self, url, kwdict):
self.data.append((Message.Url, url, self._filter(kwdict))) self.data.append((Message.Url, url, self._filter(kwdict)))

View File

@@ -528,7 +528,7 @@ class PathFormat():
self.filename_formatter = Formatter( self.filename_formatter = Formatter(
filename_fmt, kwdefault).format_map filename_fmt, kwdefault).format_map
except Exception as exc: except Exception as exc:
raise exception.FormatError(exc, "filename") raise exception.FilenameFormatError(exc)
try: try:
self.directory_formatters = [ self.directory_formatters = [
@@ -536,7 +536,7 @@ class PathFormat():
for dirfmt in directory_fmt for dirfmt in directory_fmt
] ]
except Exception as exc: except Exception as exc:
raise exception.FormatError(exc, "directory") raise exception.DirectoryFormatError(exc)
self.directory = self.realdirectory = "" self.directory = self.realdirectory = ""
self.filename = "" self.filename = ""
@@ -616,7 +616,7 @@ class PathFormat():
if segment: if segment:
append(self.clean_segment(segment)) append(self.clean_segment(segment))
except Exception as exc: except Exception as exc:
raise exception.FormatError(exc, "directory") raise exception.DirectoryFormatError(exc)
# Join path segements # Join path segements
sep = os.sep sep = os.sep
@@ -673,7 +673,7 @@ class PathFormat():
self.filename = filename = self.clean_path(self.clean_segment( self.filename = filename = self.clean_path(self.clean_segment(
self.filename_formatter(self.kwdict))) self.filename_formatter(self.kwdict)))
except Exception as exc: except Exception as exc:
raise exception.FormatError(exc, "filename") raise exception.FilenameFormatError(exc)
# Combine directory and filename to full paths # Combine directory and filename to full paths
self.path = self.directory + filename self.path = self.directory + filename