From bed1581cf0daaed45b6d71a8aa54f1e716201bc3 Mon Sep 17 00:00:00 2001 From: Maks Snegov Date: Thu, 20 Feb 2025 20:38:56 -0800 Subject: [PATCH] robocyp.py improve error handling --- robocyp.py | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/robocyp.py b/robocyp.py index 5960b47..0cd26ea 100755 --- a/robocyp.py +++ b/robocyp.py @@ -3,6 +3,7 @@ import argparse import csv import os import sys +from typing import Optional, Iterable from google.auth.transport.requests import Request from google.auth.exceptions import RefreshError @@ -21,6 +22,11 @@ DEFAULT_FORMAT = "bestvideo[height<=720][ext=mp4]+bestaudio/best[height<=720]" program_dir = os.path.dirname(os.path.realpath(__file__)) +class ErrorReasons: + QUOTA_EXCEEDED = 'quotaExceeded' + PLAYLIST_ITEMS_NOT_ACCESSIBLE = 'playlistItemsNotAccessible' + + def _truncate_title(title: str, length: int = 30) -> str: if length <= 0: return "" @@ -71,12 +77,15 @@ def get_yt_creds(): return creds -def exit_on_exceeded_quota(e: HttpError): - if e.resp.status == 403: - for error in e.error_details: - if error.get('reason') == 'quotaExceeded': - print('Youtube quota exceeded, exiting') - sys.exit(1) +def handle_http_error( + e: HttpError, + msg: Optional[str] = None, + reasons_to_abort: Optional[Iterable[str]] = (ErrorReasons.QUOTA_EXCEEDED,) +): + for error in e.error_details: + print(f"{msg}: {error.get('message')}") + if error.get('reason') in reasons_to_abort: + sys.exit(1) def read_playlists_file(): @@ -127,8 +136,7 @@ def list_playlist(yt_api, playlist_id: str): for item in response['items']: videos.append(item) except HttpError as e: - exit_on_exceeded_quota(e) - print(f'Error getting video IDs from playlist {playlist_name}: {e}') + handle_http_error(e, f'Error getting video IDs from playlist {playlist_name}') print(f'Fetched {fetched} videos from playlist {playlist_name}') return videos @@ -162,9 +170,11 @@ def add_video_to_playlist(yt_api, video_id: str, playlist_id: str, f" to playlist {playlist_name}") return True except HttpError as e: - exit_on_exceeded_quota(e) - print(f"Error adding video '{video_title}' [{video_id}]" - f" to playlist {playlist_name}: {e}") + msg = (f"Error adding video '{video_title}' [{video_id}]" + f" to playlist {playlist_name}") + reasons_to_abort = (ErrorReasons.QUOTA_EXCEEDED, + ErrorReasons.PLAYLIST_ITEMS_NOT_ACCESSIBLE) + handle_http_error(e, msg, reasons_to_abort) return False @@ -186,9 +196,9 @@ def remove_video_from_playlist(yt_api, plitem_id: str, playlist_id: str, f" from playlist {playlist_name}") return True except HttpError as e: - exit_on_exceeded_quota(e) - print(f"Error removing video '{video_title}' [{video_id}]" - f" from playlist {playlist_name}: {e}") + msg = (f"Error removing video '{video_title}' [{video_id}]" + f" from playlist {playlist_name}") + handle_http_error(e, msg) return False @@ -233,8 +243,8 @@ def get_video_info(youtube, video_id: str): id=video_id ).execute() except HttpError as e: - exit_on_exceeded_quota(e) - print(f'Error getting video {video_id}: {e}') + msg = f'Error getting video info for {video_id}' + handle_http_error(e, msg) return None if not response['items']: print(f'Video {video_id} not found') @@ -249,8 +259,8 @@ def get_playlistitem_info(youtube, playlistitem_id: str): id=playlistitem_id ).execute() except HttpError as e: - exit_on_exceeded_quota(e) - print(f'Error getting playlist item {playlistitem_id}: {e}') + msg = f'Error getting playlist item {playlistitem_id}' + handle_http_error(e, msg) return None if not response['items']: print(f'Playlist item {playlistitem_id} not found')