33import itertools
44import json
55import re
6- from typing import Iterable , Mapping , Tuple , TypeVar , Union , List
6+ from typing import Iterable , Mapping , Tuple , TypeVar , Union , List , Optional
77from urllib .parse import urlencode
88from urllib .request import Request , urlopen
99
1010from youtubesearchpython .core .constants import *
1111from youtubesearchpython .core .requests import RequestCore
12+ from youtubesearchpython .core .exceptions import YouTubeRequestError , YouTubeParseError
13+ import httpx
1214
1315
1416K = TypeVar ("K" )
@@ -20,8 +22,8 @@ class PlaylistCore(RequestCore):
2022 result = None
2123 continuationKey = None
2224
23- def __init__ (self , playlistLink : str , componentMode : str , resultMode : int , timeout : int ):
24- super ().__init__ ()
25+ def __init__ (self , playlistLink : str , componentMode : str , resultMode : int , timeout : Optional [ int ] ):
26+ super ().__init__ (timeout = timeout )
2527 self .componentMode = componentMode
2628 self .resultMode = resultMode
2729 self .timeout = timeout
@@ -40,14 +42,14 @@ def sync_create(self):
4042 if statusCode == 200 :
4143 self .post_processing ()
4244 else :
43- raise Exception ( 'ERROR: Invalid status code. ' )
45+ raise YouTubeRequestError ( f' Invalid status code { statusCode } for playlist request ' )
4446
4547 async def async_create (self ):
4648 statusCode = await self .__makeAsyncRequest ()
4749 if statusCode == 200 :
4850 self .post_processing ()
4951 else :
50- raise Exception ( 'ERROR: Invalid status code. ' )
52+ raise YouTubeRequestError ( f' Invalid status code { statusCode } for playlist async request ' )
5153
5254 def next_post_processing (self ):
5355 self .__parseSource ()
@@ -65,7 +67,7 @@ def _next(self):
6567 if statusCode .status_code == 200 :
6668 self .next_post_processing ()
6769 else :
68- raise Exception ( 'ERROR: Invalid status code. ' )
70+ raise YouTubeRequestError ( f' Invalid status code { statusCode . status_code } for playlist next request ' )
6971
7072 async def _async_next (self ):
7173 if self .continuationKey :
@@ -75,7 +77,7 @@ async def _async_next(self):
7577 if statusCode .status_code == 200 :
7678 self .next_post_processing ()
7779 else :
78- raise Exception ( 'ERROR: Invalid status code. ' )
80+ raise YouTubeRequestError ( f' Invalid status code { statusCode . status_code } for playlist async next request ' )
7981 else :
8082 await self .async_create ()
8183
@@ -123,14 +125,18 @@ def __makeNextRequest(self) -> int:
123125 try :
124126 self .response = response .text
125127 return response .status_code
126- except :
127- raise Exception ('ERROR: Could not make request.' )
128+ except (AttributeError , httpx .RequestError ) as e :
129+ raise YouTubeRequestError (f'Failed to make playlist request: { str (e )} ' )
130+ except Exception as e :
131+ raise YouTubeRequestError (f'Unexpected error making playlist request: { str (e )} ' )
128132
129133 def __parseSource (self ) -> None :
130134 try :
131135 self .responseSource = json .loads (self .response )
132- except :
133- raise Exception ('ERROR: Could not parse YouTube response.' )
136+ except json .JSONDecodeError as e :
137+ raise YouTubeParseError (f'Failed to parse JSON response for playlist: { str (e )} ' )
138+ except Exception as e :
139+ raise YouTubeParseError (f'Failed to parse YouTube playlist response: { str (e )} ' )
134140
135141 def __getComponents (self ) -> None :
136142 #print(self.responseSource)
@@ -161,7 +167,7 @@ def __getComponents(self) -> None:
161167 "isPlayable" : self .__getValue (video , ["isPlayable" ]),
162168 }
163169 videos .append (j )
164- except :
170+ except ( KeyError , AttributeError , IndexError , TypeError ) :
165171 pass
166172
167173 playlistElement = {
@@ -343,7 +349,7 @@ def __getValueEx(self, source: dict, path: List[str]) -> Iterable[Union[str, int
343349 following_key = upcoming [0 ]
344350 upcoming = upcoming [1 :]
345351 if following_key is None :
346- raise Exception ("Cannot search for a key twice consecutive or at the end with no key given" )
352+ raise ValueError ("Cannot search for a key twice consecutive or at the end with no key given" )
347353 values = self .__getAllWithKey (source , following_key )
348354 for val in values :
349355 yield from self .__getValueEx (val , path = upcoming )
0 commit comments