Skip to content

Commit 879cf04

Browse files
committed
v2.5.35: 完善异常上抛机制
1 parent e4584d0 commit 879cf04

4 files changed

Lines changed: 52 additions & 17 deletions

File tree

src/jmcomic/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# 被依赖方 <--- 使用方
33
# config <--- entity <--- toolkit <--- client <--- option <--- downloader
44

5-
__version__ = '2.5.34'
5+
__version__ = '2.5.35'
66

77
from .api import *
88
from .jm_plugin import *

src/jmcomic/api.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def download_album(jm_album_id,
4848
option=None,
4949
downloader=None,
5050
callback=None,
51+
check_exception=True,
5152
) -> Union[__DOWNLOAD_API_RET, Set[__DOWNLOAD_API_RET]]:
5253
"""
5354
下载一个本子(album),包含其所有的章节(photo)
@@ -58,6 +59,7 @@ def download_album(jm_album_id,
5859
:param option: 下载选项
5960
:param downloader: 下载器类
6061
:param callback: 返回值回调函数,可以拿到 album 和 downloader
62+
:param check_exception: 是否检查异常, 如果为True,会检查downloader是否有下载异常,并上抛PartialDownloadFailedException
6163
:return: 对于的本子实体类,下载器(如果是上述的批量情况,返回值为download_batch的返回值)
6264
"""
6365

@@ -69,7 +71,8 @@ def download_album(jm_album_id,
6971

7072
if callback is not None:
7173
callback(album, dler)
72-
74+
if check_exception:
75+
dler.raise_if_have_exception()
7376
return album, dler
7477

7578

src/jmcomic/jm_downloader.py

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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):

src/jmcomic/jm_exception.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def from_context(self, key):
1515
def __str__(self):
1616
return self.msg
1717

18+
1819
class ResponseUnexpectedException(JmcomicException):
1920
description = '响应不符合预期异常'
2021

@@ -44,7 +45,6 @@ def pattern(self):
4445

4546
class JsonResolveFailException(ResponseUnexpectedException):
4647
description = 'Json解析异常'
47-
pass
4848

4949

5050
class MissingAlbumPhotoException(ResponseUnexpectedException):
@@ -57,7 +57,10 @@ def error_jmid(self) -> str:
5757

5858
class RequestRetryAllFailException(JmcomicException):
5959
description = '请求重试全部失败异常'
60-
pass
60+
61+
62+
class PartialDownloadFailedException(JmcomicException):
63+
description = '部分章节或图片下载失败异常'
6164

6265

6366
class ExceptionTool:

0 commit comments

Comments
 (0)