overhaul exception stuff
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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)))
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user