@@ -53,7 +53,31 @@ def __init__(self, option: JmOption) -> None:
5353 # 下载成功的记录dict
5454 self .download_success_dict : Dict [JmAlbumDetail , Dict [JmPhotoDetail , List [Tuple [str , JmImageDetail ]]]] = {}
5555 # 下载失败的记录list
56- self .download_failed_list : List [Tuple [JmImageDetail , BaseException ]] = []
56+ self .download_failed_image : List [Tuple [JmImageDetail , BaseException ]] = []
57+ self .download_failed_photo : List [Tuple [JmPhotoDetail , BaseException ]] = []
58+
59+ @staticmethod
60+ def catch_exception (field_name ):
61+ def deco (func ):
62+ def wrapper (self , * args , ** kwargs ):
63+ try :
64+ return func (self , * args , ** kwargs )
65+ except Exception as e :
66+ getattr (self , field_name ).append (e )
67+ detail : JmBaseEntity = args [1 ]
68+ if detail .is_image ():
69+ detail : JmImageDetail
70+ jm_log ('image.failed' , f'图片下载失败: [{ detail .download_url } ], 异常: { e } ' )
71+
72+ elif detail .is_photo ():
73+ detail : JmPhotoDetail
74+ jm_log ('photo.failed' , f'章节下载失败: [{ detail .id } ], 异常: { e } ' )
75+
76+ raise e
77+
78+ return wrapper
79+
80+ return deco
5781
5882 def download_album (self , album_id ):
5983 client = self .client_for_album (album_id )
@@ -78,6 +102,7 @@ def download_photo(self, photo_id):
78102 self .download_by_photo_detail (photo , client )
79103 return photo
80104
105+ @catch_exception ('download_failed_photo' )
81106 def download_by_photo_detail (self , photo : JmPhotoDetail , client : JmcomicClient ):
82107 client .check_photo (photo )
83108
@@ -91,6 +116,7 @@ def download_by_photo_detail(self, photo: JmPhotoDetail, client: JmcomicClient):
91116 )
92117 self .after_photo (photo )
93118
119+ @catch_exception ('download_failed_image' )
94120 def download_by_image_detail (self , image : JmImageDetail , client : JmcomicClient ):
95121 img_save_path = self .option .decide_image_filepath (image )
96122
@@ -110,17 +136,11 @@ def download_by_image_detail(self, image: JmImageDetail, client: JmcomicClient):
110136 if use_cache is True and image .exists :
111137 return
112138
113- try :
114- client .download_by_image_detail (
115- image ,
116- img_save_path ,
117- decode_image = decode_image ,
118- )
119- except BaseException as e :
120- jm_log ('image.failed' , f'图片下载失败: [{ image .download_url } ], 异常: { e } ' )
121- # 保存失败记录
122- self .download_failed_list .append ((image , e ))
123- raise
139+ client .download_by_image_detail (
140+ image ,
141+ img_save_path ,
142+ decode_image = decode_image ,
143+ )
124144
125145 self .after_image (image , img_save_path )
126146
@@ -189,7 +209,7 @@ def all_success(self) -> bool:
189209
190210 注意!如果使用了filter机制,例如通过filter只下载3张图片,那么all_success也会为False
191211 """
192- if len (self .download_failed_list ) != 0 :
212+ if len (self .download_failed_image ) != 0 :
193213 return False
194214
195215 for album , photo_dict in self .download_success_dict .items ():
@@ -259,6 +279,15 @@ def after_image(self, image: JmImageDetail, img_save_path):
259279 downloader = self ,
260280 )
261281
282+ def raise_if_have_exception (self ):
283+ if len (self .download_failed_image ) == 0 and len (self .download_success_dict ) == 0 :
284+ return
285+ ExceptionTool .raises (
286+ f'部分下载失败: 有{ len (self .download_failed_photo )} 个章节下载失败, { len (self .download_failed_image )} 个图片下载失败' ,
287+ {'downloader' : self },
288+ PartialDownloadFailedException ,
289+ )
290+
262291 # 下面是对with语法的支持
263292
264293 def __enter__ (self ):
0 commit comments