summaryrefslogtreecommitdiffstats
path: root/gallery_dl/exception.py
diff options
context:
space:
mode:
Diffstat (limited to 'gallery_dl/exception.py')
-rw-r--r--gallery_dl/exception.py132
1 files changed, 83 insertions, 49 deletions
diff --git a/gallery_dl/exception.py b/gallery_dl/exception.py
index 6b2ce3a..5a52581 100644
--- a/gallery_dl/exception.py
+++ b/gallery_dl/exception.py
@@ -11,21 +11,26 @@
Class Hierarchy:
Exception
- +-- GalleryDLException
- +-- ExtractionError
- | +-- AuthenticationError
- | +-- AuthorizationError
- | +-- NotFoundError
- | +-- HttpError
- +-- FormatError
- | +-- FilenameFormatError
- | +-- DirectoryFormatError
- +-- FilterError
- +-- InputFileError
- +-- NoExtractorError
- +-- StopExtraction
- +-- TerminateExtraction
- +-- RestartExtraction
+ └── GalleryDLException
+ ├── ExtractionError
+ │ ├── HttpError
+ │ │ └── ChallengeError
+ │ ├── AuthorizationError
+ │ │ └── AuthRequired
+ │ ├── AuthenticationError
+ │ └── NotFoundError
+ ├── InputError
+ │ ├── FormatError
+ │ │ ├── FilenameFormatError
+ │ │ └── DirectoryFormatError
+ │ ├── FilterError
+ │ ├── InputFileError
+ │ └── NoExtractorError
+ └── ControlException
+ ├── StopExtraction
+ ├── AbortExtraction
+ ├── TerminateExtraction
+ └── RestartExtraction
"""
@@ -39,20 +44,24 @@ class GalleryDLException(Exception):
if not message:
message = self.default
elif isinstance(message, Exception):
- message = "{}: {}".format(message.__class__.__name__, message)
- if self.msgfmt and fmt:
- message = self.msgfmt.format(message)
+ message = f"{message.__class__.__name__}: {message}"
+ if fmt and self.msgfmt is not None:
+ message = self.msgfmt.replace("{}", message)
+ self.message = message
Exception.__init__(self, message)
+###############################################################################
+# Extractor Errors ############################################################
+
class ExtractionError(GalleryDLException):
"""Base class for exceptions during information extraction"""
+ code = 4
class HttpError(ExtractionError):
"""HTTP request during data extraction failed"""
default = "HTTP request failed"
- code = 4
def __init__(self, message="", response=None):
self.response = response
@@ -61,35 +70,63 @@ class HttpError(ExtractionError):
else:
self.status = response.status_code
if not message:
- message = "'{} {}' for '{}'".format(
- response.status_code, response.reason, response.url)
+ message = (f"'{response.status_code} {response.reason}' "
+ f"for '{response.url}'")
ExtractionError.__init__(self, message)
-class NotFoundError(ExtractionError):
- """Requested resource (gallery/image) could not be found"""
- msgfmt = "Requested {} could not be found"
- default = "resource (gallery/image)"
+class ChallengeError(HttpError):
code = 8
+ def __init__(self, challenge, response):
+ message = (
+ f"{challenge} ({response.status_code} {response.reason}) "
+ f"for '{response.url}'")
+ HttpError.__init__(self, message, response)
+
class AuthenticationError(ExtractionError):
"""Invalid or missing login credentials"""
- default = "Invalid or missing login credentials"
+ default = "Invalid login credentials"
code = 16
class AuthorizationError(ExtractionError):
"""Insufficient privileges to access a resource"""
- default = "Insufficient privileges to access the specified resource"
+ default = "Insufficient privileges to access this resource"
code = 16
-class FormatError(GalleryDLException):
- """Error while building output paths"""
+class AuthRequired(AuthorizationError):
+ default = "Account credentials required"
+
+ def __init__(self, required=None, message=None):
+ if required and not message:
+ if isinstance(required, str):
+ message = f"{required} required"
+ else:
+ message = f"{' or '.join(required)} required"
+ AuthorizationError.__init__(self, message)
+
+
+class NotFoundError(ExtractionError):
+ """Requested resource (gallery/image) could not be found"""
+ msgfmt = "Requested {} could not be found"
+ default = "resource (gallery/image)"
+
+
+###############################################################################
+# User Input ##################################################################
+
+class InputError(GalleryDLException):
+ """Error caused by user input and config options"""
code = 32
+class FormatError(InputError):
+ """Error while building output paths"""
+
+
class FilenameFormatError(FormatError):
"""Error while building output filenames"""
msgfmt = "Applying filename format string failed ({})"
@@ -100,40 +137,37 @@ class DirectoryFormatError(FormatError):
msgfmt = "Applying directory format string failed ({})"
-class FilterError(GalleryDLException):
+class FilterError(InputError):
"""Error while evaluating a filter expression"""
msgfmt = "Evaluating filter expression failed ({})"
- code = 32
-
-class InputFileError(GalleryDLException):
- """Error when parsing input file"""
- code = 32
- def __init__(self, message, *args):
- GalleryDLException.__init__(
- self, message % args if args else message)
+class InputFileError(InputError):
+ """Error when parsing an input file"""
-class NoExtractorError(GalleryDLException):
+class NoExtractorError(InputError):
"""No extractor can handle the given URL"""
- code = 64
-class StopExtraction(GalleryDLException):
+###############################################################################
+# Control Flow ################################################################
+
+class ControlException(GalleryDLException):
+ code = 0
+
+
+class StopExtraction(ControlException):
"""Stop data extraction"""
- def __init__(self, message=None, *args):
- GalleryDLException.__init__(self)
- self.message = message % args if args else message
- self.code = 1 if message else 0
+
+class AbortExtraction(ExtractionError, ControlException):
+ """Abort data extraction due to an error"""
-class TerminateExtraction(GalleryDLException):
+class TerminateExtraction(ControlException):
"""Terminate data extraction"""
- code = 0
-class RestartExtraction(GalleryDLException):
+class RestartExtraction(ControlException):
"""Restart data extraction"""
- code = 0