ErisPulse 1.2.8__py3-none-any.whl → 2.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ErisPulse/Core/__init__.py +19 -0
- ErisPulse/Core/adapter.py +619 -0
- ErisPulse/Core/env.py +614 -0
- ErisPulse/{logger.py → Core/logger.py} +1 -118
- ErisPulse/Core/mods.py +226 -0
- ErisPulse/Core/raiserr.py +152 -0
- ErisPulse/Core/server.py +276 -0
- ErisPulse/Core/shellprint.py +165 -0
- ErisPulse/Core/util.py +126 -0
- ErisPulse/__init__.py +654 -243
- ErisPulse/__main__.py +322 -1187
- {erispulse-1.2.8.dist-info → erispulse-2.1.0.dist-info}/METADATA +16 -41
- erispulse-2.1.0.dist-info/RECORD +16 -0
- {erispulse-1.2.8.dist-info → erispulse-2.1.0.dist-info}/entry_points.txt +1 -0
- {erispulse-1.2.8.dist-info → erispulse-2.1.0.dist-info}/licenses/LICENSE +4 -3
- ErisPulse/adapter.py +0 -465
- ErisPulse/db.py +0 -769
- ErisPulse/mods.py +0 -345
- ErisPulse/raiserr.py +0 -137
- ErisPulse/util.py +0 -144
- erispulse-1.2.8.dist-info/RECORD +0 -13
- {erispulse-1.2.8.dist-info → erispulse-2.1.0.dist-info}/WHEEL +0 -0
|
@@ -1,120 +1,3 @@
|
|
|
1
|
-
"""
|
|
2
|
-
# 日志系统
|
|
3
|
-
|
|
4
|
-
提供模块化、多级别的日志记录功能,支持内存存储和文件输出。实现了模块级别的日志控制、彩色输出和灵活的存储选项。
|
|
5
|
-
|
|
6
|
-
## API 文档
|
|
7
|
-
|
|
8
|
-
### 基本日志操作
|
|
9
|
-
|
|
10
|
-
以debug为例:
|
|
11
|
-
> 此外,还有其他级别的日志记录函数,如info, warning, error, critical等,用法相同。
|
|
12
|
-
|
|
13
|
-
debug(msg: str, *args: Any, **kwargs: Any) -> None
|
|
14
|
-
|
|
15
|
-
记录调试级别的日志信息。
|
|
16
|
-
- 参数:
|
|
17
|
-
- msg: 日志消息
|
|
18
|
-
- *args: 传递给底层logger的位置参数
|
|
19
|
-
- **kwargs: 传递给底层logger的关键字参数
|
|
20
|
-
- 返回:
|
|
21
|
-
- None
|
|
22
|
-
- 示例:
|
|
23
|
-
|
|
24
|
-
```python
|
|
25
|
-
sdk.logger.debug("这是一条日志")
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### 日志级别控制
|
|
29
|
-
#### set_level(level: str) -> None
|
|
30
|
-
设置全局日志级别。
|
|
31
|
-
- 参数:
|
|
32
|
-
- level: 日志级别,可选值为 "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"
|
|
33
|
-
- 返回:
|
|
34
|
-
- None
|
|
35
|
-
- 示例:
|
|
36
|
-
```python
|
|
37
|
-
# 设置为调试级别
|
|
38
|
-
sdk.logger.set_level("DEBUG")
|
|
39
|
-
|
|
40
|
-
# 设置为生产环境级别
|
|
41
|
-
sdk.logger.set_level("INFO")
|
|
42
|
-
|
|
43
|
-
# 根据环境设置日志级别
|
|
44
|
-
if is_production():
|
|
45
|
-
sdk.logger.set_level("WARNING")
|
|
46
|
-
else:
|
|
47
|
-
sdk.logger.set_level("DEBUG")
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
#### set_module_level(module_name: str, level: str) -> bool
|
|
51
|
-
设置特定模块的日志级别。
|
|
52
|
-
- 参数:
|
|
53
|
-
- module_name: 模块名称
|
|
54
|
-
- level: 日志级别,可选值为 "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"
|
|
55
|
-
- 返回:
|
|
56
|
-
- bool: 设置是否成功
|
|
57
|
-
- 示例:
|
|
58
|
-
```python
|
|
59
|
-
# 为特定模块设置详细日志
|
|
60
|
-
sdk.logger.set_module_level("NetworkModule", "DEBUG")
|
|
61
|
-
|
|
62
|
-
# 为敏感模块设置更高级别
|
|
63
|
-
sdk.logger.set_module_level("AuthModule", "WARNING")
|
|
64
|
-
|
|
65
|
-
# 根据配置设置模块日志级别
|
|
66
|
-
for module, level in config.get("logging", {}).items():
|
|
67
|
-
success = sdk.logger.set_module_level(module, level)
|
|
68
|
-
if not success:
|
|
69
|
-
print(f"无法为模块 {module} 设置日志级别 {level}")
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### 日志存储和输出
|
|
73
|
-
#### set_output_file(path: Union[str, List[str]]) -> None
|
|
74
|
-
设置日志输出文件。
|
|
75
|
-
- 参数:
|
|
76
|
-
- path: 日志文件路径,可以是单个字符串或路径列表
|
|
77
|
-
- 返回:
|
|
78
|
-
- None
|
|
79
|
-
- 异常:
|
|
80
|
-
- 如果无法设置日志文件,会抛出异常
|
|
81
|
-
- 示例:
|
|
82
|
-
```python
|
|
83
|
-
# 设置单个日志文件
|
|
84
|
-
sdk.logger.set_output_file("app.log")
|
|
85
|
-
|
|
86
|
-
# 设置多个日志文件
|
|
87
|
-
sdk.logger.set_output_file(["app.log", "debug.log"])
|
|
88
|
-
|
|
89
|
-
# 使用日期命名日志文件
|
|
90
|
-
from datetime import datetime
|
|
91
|
-
log_file = f"logs/app_{datetime.now().strftime('%Y%m%d')}.log"
|
|
92
|
-
sdk.logger.set_output_file(log_file)
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
#### save_logs(path: Union[str, List[str]]) -> None
|
|
96
|
-
保存内存中的日志到文件。
|
|
97
|
-
- 参数:
|
|
98
|
-
- path: 保存路径,可以是单个字符串或路径列表
|
|
99
|
-
- 返回:
|
|
100
|
-
- None
|
|
101
|
-
- 异常:
|
|
102
|
-
- 如果无法保存日志,会抛出异常
|
|
103
|
-
- 示例:
|
|
104
|
-
```python
|
|
105
|
-
# 保存到单个文件
|
|
106
|
-
sdk.logger.save_logs("saved_logs.txt")
|
|
107
|
-
|
|
108
|
-
# 保存到多个文件
|
|
109
|
-
sdk.logger.save_logs(["main_log.txt", "backup_log.txt"])
|
|
110
|
-
|
|
111
|
-
# 在应用退出前保存日志
|
|
112
|
-
import atexit
|
|
113
|
-
atexit.register(lambda: sdk.logger.save_logs("final_logs.txt"))
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
"""
|
|
117
|
-
|
|
118
1
|
import logging
|
|
119
2
|
import inspect
|
|
120
3
|
import datetime
|
|
@@ -144,7 +27,7 @@ class Logger:
|
|
|
144
27
|
return False
|
|
145
28
|
|
|
146
29
|
def set_module_level(self, module_name: str, level: str) -> bool:
|
|
147
|
-
from .
|
|
30
|
+
from .env import env
|
|
148
31
|
if not env.get_module_status(module_name):
|
|
149
32
|
self._logger.warning(f"模块 {module_name} 未启用,无法设置日志等级。")
|
|
150
33
|
return False
|
ErisPulse/Core/mods.py
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ErisPulse 模块管理器
|
|
3
|
+
|
|
4
|
+
提供模块的注册、状态管理和依赖关系处理功能。支持模块的启用/禁用、版本控制和依赖解析。
|
|
5
|
+
|
|
6
|
+
{!--< tips >!--}
|
|
7
|
+
1. 使用模块前缀区分不同模块的配置
|
|
8
|
+
2. 支持模块状态持久化存储
|
|
9
|
+
3. 自动处理模块间的依赖关系
|
|
10
|
+
{!--< /tips >!--}
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
from typing import Dict, Optional, Any, List, Set, Tuple, Union, Type, FrozenSet
|
|
15
|
+
|
|
16
|
+
class ModuleManager:
|
|
17
|
+
"""
|
|
18
|
+
模块管理器
|
|
19
|
+
|
|
20
|
+
管理所有模块的注册、状态和依赖关系
|
|
21
|
+
|
|
22
|
+
{!--< tips >!--}
|
|
23
|
+
1. 通过set_module/get_module管理模块信息
|
|
24
|
+
2. 通过set_module_status/get_module_status控制模块状态
|
|
25
|
+
3. 通过set_all_modules/get_all_modules批量操作模块
|
|
26
|
+
{!--< /tips >!--}
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
DEFAULT_MODULE_PREFIX = "erispulse.module.data:"
|
|
30
|
+
DEFAULT_STATUS_PREFIX = "erispulse.module.status:"
|
|
31
|
+
|
|
32
|
+
def __init__(self):
|
|
33
|
+
from .env import env
|
|
34
|
+
self.env = env
|
|
35
|
+
self._ensure_prefixes()
|
|
36
|
+
|
|
37
|
+
def _ensure_prefixes(self) -> None:
|
|
38
|
+
"""
|
|
39
|
+
{!--< internal-use >!--}
|
|
40
|
+
确保模块前缀配置存在
|
|
41
|
+
"""
|
|
42
|
+
if not self.env.get("erispulse.system.module_prefix"):
|
|
43
|
+
self.env.set("erispulse.system.module_prefix", self.DEFAULT_MODULE_PREFIX)
|
|
44
|
+
if not self.env.get("erispulse.system.status_prefix"):
|
|
45
|
+
self.env.set("erispulse.system.status_prefix", self.DEFAULT_STATUS_PREFIX)
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def module_prefix(self) -> str:
|
|
49
|
+
"""
|
|
50
|
+
获取模块数据前缀
|
|
51
|
+
|
|
52
|
+
:return: 模块数据前缀字符串
|
|
53
|
+
"""
|
|
54
|
+
return self.env.get("erispulse.system.module_prefix")
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def status_prefix(self) -> str:
|
|
58
|
+
"""
|
|
59
|
+
获取模块状态前缀
|
|
60
|
+
|
|
61
|
+
:return: 模块状态前缀字符串
|
|
62
|
+
"""
|
|
63
|
+
return self.env.get("erispulse.system.status_prefix")
|
|
64
|
+
|
|
65
|
+
def set_module_status(self, module_name: str, status: bool) -> None:
|
|
66
|
+
"""
|
|
67
|
+
设置模块启用状态
|
|
68
|
+
|
|
69
|
+
:param module_name: 模块名称
|
|
70
|
+
:param status: 启用状态
|
|
71
|
+
|
|
72
|
+
:example:
|
|
73
|
+
>>> # 启用模块
|
|
74
|
+
>>> mods.set_module_status("MyModule", True)
|
|
75
|
+
>>> # 禁用模块
|
|
76
|
+
>>> mods.set_module_status("MyModule", False)
|
|
77
|
+
"""
|
|
78
|
+
self.env.set(f"{self.status_prefix}{module_name}", bool(status))
|
|
79
|
+
|
|
80
|
+
module_info = self.get_module(module_name)
|
|
81
|
+
if module_info:
|
|
82
|
+
module_info["status"] = bool(status)
|
|
83
|
+
self.env.set(f"{self.module_prefix}{module_name}", module_info)
|
|
84
|
+
|
|
85
|
+
def get_module_status(self, module_name: str) -> bool:
|
|
86
|
+
"""
|
|
87
|
+
获取模块启用状态
|
|
88
|
+
|
|
89
|
+
:param module_name: 模块名称
|
|
90
|
+
:return: 模块是否启用
|
|
91
|
+
|
|
92
|
+
:example:
|
|
93
|
+
>>> if mods.get_module_status("MyModule"):
|
|
94
|
+
>>> print("模块已启用")
|
|
95
|
+
"""
|
|
96
|
+
status = self.env.get(f"{self.status_prefix}{module_name}", True)
|
|
97
|
+
if isinstance(status, str):
|
|
98
|
+
return status.lower() == 'true'
|
|
99
|
+
return bool(status)
|
|
100
|
+
|
|
101
|
+
def set_module(self, module_name: str, module_info: Dict[str, Any]) -> None:
|
|
102
|
+
"""
|
|
103
|
+
设置模块信息
|
|
104
|
+
|
|
105
|
+
:param module_name: 模块名称
|
|
106
|
+
:param module_info: 模块信息字典
|
|
107
|
+
|
|
108
|
+
:example:
|
|
109
|
+
>>> mods.set_module("MyModule", {
|
|
110
|
+
>>> "version": "1.0.0",
|
|
111
|
+
>>> "description": "我的模块",
|
|
112
|
+
>>> "status": True
|
|
113
|
+
>>> })
|
|
114
|
+
"""
|
|
115
|
+
self.env.set(f"{self.module_prefix}{module_name}", module_info)
|
|
116
|
+
self.set_module_status(module_name, module_info.get('status', True))
|
|
117
|
+
|
|
118
|
+
def get_module(self, module_name: str) -> Optional[Dict[str, Any]]:
|
|
119
|
+
"""
|
|
120
|
+
获取模块信息
|
|
121
|
+
|
|
122
|
+
:param module_name: 模块名称
|
|
123
|
+
:return: 模块信息字典或None
|
|
124
|
+
|
|
125
|
+
:example:
|
|
126
|
+
>>> module_info = mods.get_module("MyModule")
|
|
127
|
+
>>> if module_info:
|
|
128
|
+
>>> print(f"模块版本: {module_info.get('version')}")
|
|
129
|
+
"""
|
|
130
|
+
return self.env.get(f"{self.module_prefix}{module_name}")
|
|
131
|
+
|
|
132
|
+
def set_all_modules(self, modules_info: Dict[str, Dict[str, Any]]) -> None:
|
|
133
|
+
"""
|
|
134
|
+
批量设置多个模块信息
|
|
135
|
+
|
|
136
|
+
:param modules_info: 模块信息字典
|
|
137
|
+
|
|
138
|
+
:example:
|
|
139
|
+
>>> mods.set_all_modules({
|
|
140
|
+
>>> "Module1": {"version": "1.0", "status": True},
|
|
141
|
+
>>> "Module2": {"version": "2.0", "status": False}
|
|
142
|
+
>>> })
|
|
143
|
+
"""
|
|
144
|
+
for module_name, module_info in modules_info.items():
|
|
145
|
+
self.set_module(module_name, module_info)
|
|
146
|
+
|
|
147
|
+
def get_all_modules(self) -> Dict[str, Dict[str, Any]]:
|
|
148
|
+
"""
|
|
149
|
+
获取所有模块信息
|
|
150
|
+
|
|
151
|
+
:return: 模块信息字典
|
|
152
|
+
|
|
153
|
+
:example:
|
|
154
|
+
>>> all_modules = mods.get_all_modules()
|
|
155
|
+
>>> for name, info in all_modules.items():
|
|
156
|
+
>>> print(f"{name}: {info.get('status')}")
|
|
157
|
+
"""
|
|
158
|
+
modules_info = {}
|
|
159
|
+
all_keys = self.env.get_all_keys()
|
|
160
|
+
prefix_len = len(self.module_prefix)
|
|
161
|
+
|
|
162
|
+
for key in all_keys:
|
|
163
|
+
if key.startswith(self.module_prefix):
|
|
164
|
+
module_name = key[prefix_len:]
|
|
165
|
+
module_info = self.get_module(module_name)
|
|
166
|
+
if module_info:
|
|
167
|
+
status = self.get_module_status(module_name)
|
|
168
|
+
module_info['status'] = bool(status)
|
|
169
|
+
modules_info[module_name] = module_info
|
|
170
|
+
return modules_info
|
|
171
|
+
|
|
172
|
+
def update_module(self, module_name: str, module_info: Dict[str, Any]) -> None:
|
|
173
|
+
"""
|
|
174
|
+
更新模块信息
|
|
175
|
+
|
|
176
|
+
:param module_name: 模块名称
|
|
177
|
+
:param module_info: 完整的模块信息字典
|
|
178
|
+
"""
|
|
179
|
+
self.set_module(module_name, module_info)
|
|
180
|
+
|
|
181
|
+
def remove_module(self, module_name: str) -> bool:
|
|
182
|
+
"""
|
|
183
|
+
移除模块
|
|
184
|
+
|
|
185
|
+
:param module_name: 模块名称
|
|
186
|
+
:return: 是否成功移除
|
|
187
|
+
|
|
188
|
+
:example:
|
|
189
|
+
>>> if mods.remove_module("OldModule"):
|
|
190
|
+
>>> print("模块已移除")
|
|
191
|
+
"""
|
|
192
|
+
module_key = f"{self.module_prefix}{module_name}"
|
|
193
|
+
status_key = f"{self.status_prefix}{module_name}"
|
|
194
|
+
|
|
195
|
+
if self.env.get(module_key) is not None:
|
|
196
|
+
self.env.delete(module_key)
|
|
197
|
+
self.env.delete(status_key)
|
|
198
|
+
return True
|
|
199
|
+
return False
|
|
200
|
+
|
|
201
|
+
def update_prefixes(self, module_prefix: Optional[str] = None, status_prefix: Optional[str] = None) -> None:
|
|
202
|
+
"""
|
|
203
|
+
更新模块前缀配置
|
|
204
|
+
|
|
205
|
+
:param module_prefix: 新的模块数据前缀(可选)
|
|
206
|
+
:param status_prefix: 新的模块状态前缀(可选)
|
|
207
|
+
|
|
208
|
+
:example:
|
|
209
|
+
>>> # 更新模块前缀
|
|
210
|
+
>>> mods.update_prefixes(
|
|
211
|
+
>>> module_prefix="custom.module.data:",
|
|
212
|
+
>>> status_prefix="custom.module.status:"
|
|
213
|
+
>>> )
|
|
214
|
+
"""
|
|
215
|
+
if module_prefix:
|
|
216
|
+
if not module_prefix.endswith(':'):
|
|
217
|
+
module_prefix += ':'
|
|
218
|
+
self.env.set("erispulse.system.module_prefix", module_prefix)
|
|
219
|
+
|
|
220
|
+
if status_prefix:
|
|
221
|
+
if not status_prefix.endswith(':'):
|
|
222
|
+
status_prefix += ':'
|
|
223
|
+
self.env.set("erispulse.system.status_prefix", status_prefix)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
mods = ModuleManager()
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ErisPulse 错误管理系统
|
|
3
|
+
|
|
4
|
+
提供错误类型注册、抛出和管理功能,集成全局异常处理。支持自定义错误类型、错误链追踪和全局异常捕获。
|
|
5
|
+
|
|
6
|
+
{!--< tips >!--}
|
|
7
|
+
1. 使用register注册自定义错误类型
|
|
8
|
+
2. 通过info获取错误信息
|
|
9
|
+
3. 自动捕获未处理异常
|
|
10
|
+
{!--< /tips >!--}
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import sys
|
|
14
|
+
import traceback
|
|
15
|
+
import asyncio
|
|
16
|
+
from typing import Dict, Any, Optional, Type, Callable, List, Set, Tuple, Union
|
|
17
|
+
|
|
18
|
+
class Error:
|
|
19
|
+
"""
|
|
20
|
+
错误管理器
|
|
21
|
+
|
|
22
|
+
提供错误类型注册和抛出功能
|
|
23
|
+
|
|
24
|
+
{!--< tips >!--}
|
|
25
|
+
1. 通过register方法注册自定义错误类型
|
|
26
|
+
2. 通过动态属性访问抛出错误
|
|
27
|
+
3. 通过info方法获取错误信息
|
|
28
|
+
{!--< /tips >!--}
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self):
|
|
32
|
+
self._types = {}
|
|
33
|
+
|
|
34
|
+
def register(self, name: str, doc: str = "", base: Type[Exception] = Exception) -> Type[Exception]:
|
|
35
|
+
"""
|
|
36
|
+
注册新的错误类型
|
|
37
|
+
|
|
38
|
+
:param name: 错误类型名称
|
|
39
|
+
:param doc: 错误描述文档
|
|
40
|
+
:param base: 基础异常类
|
|
41
|
+
:return: 注册的错误类
|
|
42
|
+
|
|
43
|
+
:example:
|
|
44
|
+
>>> # 注册简单错误
|
|
45
|
+
>>> raiserr.register("SimpleError", "简单的错误类型")
|
|
46
|
+
>>> # 注册自定义基类的错误
|
|
47
|
+
>>> raiserr.register("AdvancedError", "高级错误", CustomBaseError)
|
|
48
|
+
"""
|
|
49
|
+
if name not in self._types:
|
|
50
|
+
err_cls = type(name, (base,), {"__doc__": doc})
|
|
51
|
+
self._types[name] = err_cls
|
|
52
|
+
return self._types[name]
|
|
53
|
+
|
|
54
|
+
def __getattr__(self, name: str) -> Callable[..., None]:
|
|
55
|
+
"""
|
|
56
|
+
动态获取错误抛出函数
|
|
57
|
+
|
|
58
|
+
:param name: 错误类型名称
|
|
59
|
+
:return: 错误抛出函数
|
|
60
|
+
|
|
61
|
+
:raises AttributeError: 当错误类型未注册时抛出
|
|
62
|
+
"""
|
|
63
|
+
def raiser(msg: str, exit: bool = False) -> None:
|
|
64
|
+
"""
|
|
65
|
+
错误抛出函数
|
|
66
|
+
|
|
67
|
+
:param msg: 错误消息
|
|
68
|
+
:param exit: 是否退出程序
|
|
69
|
+
"""
|
|
70
|
+
from .logger import logger
|
|
71
|
+
err_cls = self._types.get(name) or self.register(name)
|
|
72
|
+
exc = err_cls(msg)
|
|
73
|
+
|
|
74
|
+
red = '\033[91m'
|
|
75
|
+
reset = '\033[0m'
|
|
76
|
+
|
|
77
|
+
logger.error(f"{red}{name}: {msg} | {err_cls.__doc__}{reset}")
|
|
78
|
+
logger.error(f"{red}{ ''.join(traceback.format_stack()) }{reset}")
|
|
79
|
+
|
|
80
|
+
if exit:
|
|
81
|
+
raise exc
|
|
82
|
+
return raiser
|
|
83
|
+
|
|
84
|
+
def info(self, name: Optional[str] = None) -> Dict[str, Any]:
|
|
85
|
+
"""
|
|
86
|
+
获取错误信息
|
|
87
|
+
|
|
88
|
+
:param name: 错误类型名称(可选)
|
|
89
|
+
:return: 错误信息字典
|
|
90
|
+
|
|
91
|
+
:example:
|
|
92
|
+
>>> # 获取特定错误信息
|
|
93
|
+
>>> error_info = raiserr.info("SimpleError")
|
|
94
|
+
>>> # 获取所有错误信息
|
|
95
|
+
>>> all_errors = raiserr.info()
|
|
96
|
+
"""
|
|
97
|
+
result = {}
|
|
98
|
+
for err_name, err_cls in self._types.items():
|
|
99
|
+
result[err_name] = {
|
|
100
|
+
"type": err_name,
|
|
101
|
+
"doc": getattr(err_cls, "__doc__", ""),
|
|
102
|
+
"class": err_cls,
|
|
103
|
+
}
|
|
104
|
+
if name is None:
|
|
105
|
+
return result
|
|
106
|
+
err_cls = self._types.get(name)
|
|
107
|
+
if not err_cls:
|
|
108
|
+
return {
|
|
109
|
+
"type": None,
|
|
110
|
+
"doc": None,
|
|
111
|
+
"class": None,
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
"type": name,
|
|
115
|
+
"doc": getattr(err_cls, "__doc__", ""),
|
|
116
|
+
"class": err_cls,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
raiserr = Error()
|
|
121
|
+
|
|
122
|
+
# 全局异常处理器
|
|
123
|
+
def global_exception_handler(exc_type: Type[Exception], exc_value: Exception, exc_traceback: Any) -> None:
|
|
124
|
+
"""
|
|
125
|
+
{!--< internal-use >!--}
|
|
126
|
+
全局异常处理器
|
|
127
|
+
|
|
128
|
+
:param exc_type: 异常类型
|
|
129
|
+
:param exc_value: 异常值
|
|
130
|
+
:param exc_traceback: 追踪信息
|
|
131
|
+
"""
|
|
132
|
+
error_message = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback))
|
|
133
|
+
raiserr.ExternalError(
|
|
134
|
+
f"{exc_type.__name__}: {exc_value}\nTraceback:\n{error_message}"
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
def async_exception_handler(loop: asyncio.AbstractEventLoop, context: Dict[str, Any]) -> None:
|
|
138
|
+
"""
|
|
139
|
+
{!--< internal-use >!--}
|
|
140
|
+
异步异常处理器
|
|
141
|
+
|
|
142
|
+
:param loop: 事件循环
|
|
143
|
+
:param context: 上下文字典
|
|
144
|
+
"""
|
|
145
|
+
exception = context.get('exception')
|
|
146
|
+
tb = ''.join(traceback.format_exception(type(exception), exception, exception.__traceback__))
|
|
147
|
+
raiserr.ExternalError(
|
|
148
|
+
f"{type(exception).__name__}: {exception}\nTraceback:\n{tb}"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
sys.excepthook = global_exception_handler
|
|
152
|
+
asyncio.get_event_loop().set_exception_handler(async_exception_handler)
|