mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-10 01:02:13 +01:00
Separate the options --ignore-errors
and --no-abort-on-error
In youtube-dl, `-i` ignores both download and post-processing error, and treats the download as successful even if the post-processor fails. yt-dlp used to skip the entire video on either error and there was no option to ignore the post-processing errors like youtube-dl does. By splitting the option into two, now either just the download errors (--no-abort-on-error, default on CLI) or all errors (--ignore-errors) can be ignored as per the users' needs Closes #893
This commit is contained in:
parent
1f8471e22c
commit
b19404591a
7 changed files with 32 additions and 19 deletions
|
@ -243,9 +243,12 @@ ## General Options:
|
||||||
-U, --update Update this program to latest version. Make
|
-U, --update Update this program to latest version. Make
|
||||||
sure that you have sufficient permissions
|
sure that you have sufficient permissions
|
||||||
(run with sudo if needed)
|
(run with sudo if needed)
|
||||||
-i, --ignore-errors Continue on download errors, for example to
|
-i, --ignore-errors Ignore download and postprocessing errors.
|
||||||
skip unavailable videos in a playlist
|
The download will be considered successfull
|
||||||
(default) (Alias: --no-abort-on-error)
|
even if the postprocessing fails
|
||||||
|
--no-abort-on-error Continue with next video on download
|
||||||
|
errors; e.g. to skip unavailable videos in
|
||||||
|
a playlist (default)
|
||||||
--abort-on-error Abort downloading of further videos if an
|
--abort-on-error Abort downloading of further videos if an
|
||||||
error occurs (Alias: --no-ignore-errors)
|
error occurs (Alias: --no-ignore-errors)
|
||||||
--dump-user-agent Display the current user-agent and exit
|
--dump-user-agent Display the current user-agent and exit
|
||||||
|
|
|
@ -226,9 +226,9 @@ class YoutubeDL(object):
|
||||||
restrictfilenames: Do not allow "&" and spaces in file names
|
restrictfilenames: Do not allow "&" and spaces in file names
|
||||||
trim_file_name: Limit length of filename (extension excluded)
|
trim_file_name: Limit length of filename (extension excluded)
|
||||||
windowsfilenames: Force the filenames to be windows compatible
|
windowsfilenames: Force the filenames to be windows compatible
|
||||||
ignoreerrors: Do not stop on download errors
|
ignoreerrors: Do not stop on download/postprocessing errors.
|
||||||
(Default True when running yt-dlp,
|
Can be 'only_download' to ignore only download errors.
|
||||||
but False when directly accessing YoutubeDL class)
|
Default is 'only_download' for CLI, but False for API
|
||||||
skip_playlist_after_errors: Number of allowed failures until the rest of
|
skip_playlist_after_errors: Number of allowed failures until the rest of
|
||||||
the playlist is skipped
|
the playlist is skipped
|
||||||
force_generic_extractor: Force downloader to use the generic extractor
|
force_generic_extractor: Force downloader to use the generic extractor
|
||||||
|
@ -776,7 +776,7 @@ def trouble(self, message=None, tb=None):
|
||||||
tb = ''.join(tb_data)
|
tb = ''.join(tb_data)
|
||||||
if tb:
|
if tb:
|
||||||
self.to_stderr(tb)
|
self.to_stderr(tb)
|
||||||
if not self.params.get('ignoreerrors', False):
|
if not self.params.get('ignoreerrors'):
|
||||||
if sys.exc_info()[0] and hasattr(sys.exc_info()[1], 'exc_info') and sys.exc_info()[1].exc_info[0]:
|
if sys.exc_info()[0] and hasattr(sys.exc_info()[1], 'exc_info') and sys.exc_info()[1].exc_info[0]:
|
||||||
exc_info = sys.exc_info()[1].exc_info
|
exc_info = sys.exc_info()[1].exc_info
|
||||||
else:
|
else:
|
||||||
|
@ -1241,7 +1241,7 @@ def wrapper(self, *args, **kwargs):
|
||||||
except (MaxDownloadsReached, ExistingVideoReached, RejectedVideoReached, LazyList.IndexError):
|
except (MaxDownloadsReached, ExistingVideoReached, RejectedVideoReached, LazyList.IndexError):
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if self.params.get('ignoreerrors', False):
|
if self.params.get('ignoreerrors'):
|
||||||
self.report_error(error_to_compat_str(e), tb=encode_compat_str(traceback.format_exc()))
|
self.report_error(error_to_compat_str(e), tb=encode_compat_str(traceback.format_exc()))
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
@ -2989,10 +2989,17 @@ def run_pp(self, pp, infodict):
|
||||||
files_to_delete = []
|
files_to_delete = []
|
||||||
if '__files_to_move' not in infodict:
|
if '__files_to_move' not in infodict:
|
||||||
infodict['__files_to_move'] = {}
|
infodict['__files_to_move'] = {}
|
||||||
|
try:
|
||||||
files_to_delete, infodict = pp.run(infodict)
|
files_to_delete, infodict = pp.run(infodict)
|
||||||
|
except PostProcessingError as e:
|
||||||
|
# Must be True and not 'only_download'
|
||||||
|
if self.params.get('ignoreerrors') is True:
|
||||||
|
self.report_error(e)
|
||||||
|
return infodict
|
||||||
|
raise
|
||||||
|
|
||||||
if not files_to_delete:
|
if not files_to_delete:
|
||||||
return infodict
|
return infodict
|
||||||
|
|
||||||
if self.params.get('keepvideo', False):
|
if self.params.get('keepvideo', False):
|
||||||
for f in files_to_delete:
|
for f in files_to_delete:
|
||||||
infodict['__files_to_move'].setdefault(f, '')
|
infodict['__files_to_move'].setdefault(f, '')
|
||||||
|
|
|
@ -279,7 +279,7 @@ def set_default_compat(compat_name, opt_name, default=True, remove_compat=True):
|
||||||
setattr(opts, opt_name, default)
|
setattr(opts, opt_name, default)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
set_default_compat('abort-on-error', 'ignoreerrors')
|
set_default_compat('abort-on-error', 'ignoreerrors', 'only_download')
|
||||||
set_default_compat('no-playlist-metafiles', 'allow_playlist_files')
|
set_default_compat('no-playlist-metafiles', 'allow_playlist_files')
|
||||||
set_default_compat('no-clean-infojson', 'clean_infojson')
|
set_default_compat('no-clean-infojson', 'clean_infojson')
|
||||||
if 'format-sort' in compat_opts:
|
if 'format-sort' in compat_opts:
|
||||||
|
|
|
@ -206,9 +206,13 @@ def _dict_from_options_callback(
|
||||||
action='store_true', dest='update_self',
|
action='store_true', dest='update_self',
|
||||||
help='Update this program to latest version. Make sure that you have sufficient permissions (run with sudo if needed)')
|
help='Update this program to latest version. Make sure that you have sufficient permissions (run with sudo if needed)')
|
||||||
general.add_option(
|
general.add_option(
|
||||||
'-i', '--ignore-errors', '--no-abort-on-error',
|
'-i', '--ignore-errors',
|
||||||
action='store_true', dest='ignoreerrors', default=None,
|
action='store_true', dest='ignoreerrors',
|
||||||
help='Continue on download errors, for example to skip unavailable videos in a playlist (default) (Alias: --no-abort-on-error)')
|
help='Ignore download and postprocessing errors. The download will be considered successfull even if the postprocessing fails')
|
||||||
|
general.add_option(
|
||||||
|
'--no-abort-on-error',
|
||||||
|
action='store_const', dest='ignoreerrors', const='only_download',
|
||||||
|
help='Continue with next video on download errors; e.g. to skip unavailable videos in a playlist (default)')
|
||||||
general.add_option(
|
general.add_option(
|
||||||
'--abort-on-error', '--no-ignore-errors',
|
'--abort-on-error', '--no-ignore-errors',
|
||||||
action='store_false', dest='ignoreerrors',
|
action='store_false', dest='ignoreerrors',
|
||||||
|
|
|
@ -52,6 +52,7 @@ def report_warning(self, text, *args, **kwargs):
|
||||||
return self._downloader.report_warning(text, *args, **kwargs)
|
return self._downloader.report_warning(text, *args, **kwargs)
|
||||||
|
|
||||||
def report_error(self, text, *args, **kwargs):
|
def report_error(self, text, *args, **kwargs):
|
||||||
|
# Exists only for compatibility. Do not use
|
||||||
if self._downloader:
|
if self._downloader:
|
||||||
return self._downloader.report_error(text, *args, **kwargs)
|
return self._downloader.report_error(text, *args, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -288,8 +288,7 @@ def make_args(file, args, name, number):
|
||||||
stdout, stderr = process_communicate_or_kill(p)
|
stdout, stderr = process_communicate_or_kill(p)
|
||||||
if p.returncode not in variadic(expected_retcodes):
|
if p.returncode not in variadic(expected_retcodes):
|
||||||
stderr = stderr.decode('utf-8', 'replace').strip()
|
stderr = stderr.decode('utf-8', 'replace').strip()
|
||||||
if self.get_param('verbose', False):
|
self.write_debug(stderr)
|
||||||
self.report_error(stderr)
|
|
||||||
raise FFmpegPostProcessorError(stderr.split('\n')[-1])
|
raise FFmpegPostProcessorError(stderr.split('\n')[-1])
|
||||||
for out_path, _ in output_path_opts:
|
for out_path, _ in output_path_opts:
|
||||||
if out_path:
|
if out_path:
|
||||||
|
|
|
@ -57,8 +57,7 @@ def run(self, info):
|
||||||
return [], info
|
return [], info
|
||||||
|
|
||||||
except XAttrUnavailableError as e:
|
except XAttrUnavailableError as e:
|
||||||
self.report_error(str(e))
|
raise PostProcessingError(str(e))
|
||||||
return [], info
|
|
||||||
|
|
||||||
except XAttrMetadataError as e:
|
except XAttrMetadataError as e:
|
||||||
if e.reason == 'NO_SPACE':
|
if e.reason == 'NO_SPACE':
|
||||||
|
@ -74,5 +73,5 @@ def run(self, info):
|
||||||
msg += 'You need to use NTFS.'
|
msg += 'You need to use NTFS.'
|
||||||
else:
|
else:
|
||||||
msg += '(You may have to enable them in your /etc/fstab)'
|
msg += '(You may have to enable them in your /etc/fstab)'
|
||||||
self.report_error(msg)
|
raise PostProcessingError(str(e))
|
||||||
return [], info
|
return [], info
|
||||||
|
|
Loading…
Reference in a new issue