ErisPulse 1.0.15__tar.gz → 1.0.16__tar.gz
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-1.0.15 → erispulse-1.0.16}/ErisPulse/__init__.py +12 -8
- erispulse-1.0.16/ErisPulse/adapter.py +143 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse/db.py +4 -2
- erispulse-1.0.16/ErisPulse/raiserr.py +74 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse/util.py +11 -2
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse.egg-info/PKG-INFO +1 -1
- {erispulse-1.0.15 → erispulse-1.0.16}/PKG-INFO +1 -1
- {erispulse-1.0.15 → erispulse-1.0.16}/pyproject.toml +1 -1
- erispulse-1.0.15/ErisPulse/adapter.py +0 -81
- erispulse-1.0.15/ErisPulse/raiserr.py +0 -44
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse/__main__.py +0 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse/logger.py +0 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse/mods.py +0 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse.egg-info/SOURCES.txt +0 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse.egg-info/dependency_links.txt +0 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse.egg-info/entry_points.txt +0 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse.egg-info/requires.txt +0 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/ErisPulse.egg-info/top_level.txt +0 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/README.md +0 -0
- {erispulse-1.0.15 → erispulse-1.0.16}/setup.cfg +0 -0
|
@@ -8,11 +8,8 @@ from .db import env
|
|
|
8
8
|
from .mods import mods
|
|
9
9
|
from .adapter import adapter, adapterbase
|
|
10
10
|
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
raiserr.register("InvalidDependencyError", doc="依赖无效错误")
|
|
14
|
-
raiserr.register("CycleDependencyError" , doc="依赖循环错误")
|
|
15
|
-
raiserr.register("ModuleLoadError" , doc="模块加载错误")
|
|
11
|
+
# 这里不能删,确保windows下的shell能正确显示颜色
|
|
12
|
+
os.system('')
|
|
16
13
|
|
|
17
14
|
sdk = types.SimpleNamespace()
|
|
18
15
|
setattr(sdk, "env", env)
|
|
@@ -25,6 +22,14 @@ setattr(sdk, "BaseAdapter", adapterbase)
|
|
|
25
22
|
|
|
26
23
|
env.load_env_file()
|
|
27
24
|
|
|
25
|
+
# 注册 ErrorHook 并预注册常用错误类型
|
|
26
|
+
raiserr.register("CaughtExternalError" , doc="捕获的非SDK抛出的异常")
|
|
27
|
+
raiserr.register("InitError" , doc="SDK初始化错误")
|
|
28
|
+
raiserr.register("MissingDependencyError" , doc="缺少依赖错误")
|
|
29
|
+
raiserr.register("InvalidDependencyError" , doc="依赖无效错误")
|
|
30
|
+
raiserr.register("CycleDependencyError" , doc="依赖循环错误")
|
|
31
|
+
raiserr.register("ModuleLoadError" , doc="模块加载错误")
|
|
32
|
+
|
|
28
33
|
def init():
|
|
29
34
|
try:
|
|
30
35
|
sdkModulePath = os.path.join(os.path.dirname(__file__), "modules")
|
|
@@ -156,7 +161,6 @@ def init():
|
|
|
156
161
|
logger.error(f"注册适配器失败: {e}")
|
|
157
162
|
|
|
158
163
|
except Exception as e:
|
|
159
|
-
|
|
160
|
-
raise e
|
|
164
|
+
raiserr.InitError(f"sdk初始化失败: {e}", exit=True)
|
|
161
165
|
|
|
162
|
-
sdk.init = init
|
|
166
|
+
sdk.init = init
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
import asyncio
|
|
3
|
+
from typing import Callable, Any, Dict, List, Type, Optional
|
|
4
|
+
from collections import defaultdict
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# DSL 基类,用于实现 Send.To(...).Func(...) 风格
|
|
8
|
+
class SendDSL:
|
|
9
|
+
def __init__(self, adapter: 'BaseAdapter', target_type: Optional[str] = None, target_id: Optional[str] = None):
|
|
10
|
+
self._adapter = adapter
|
|
11
|
+
self._target_type = target_type
|
|
12
|
+
self._target_id = target_id
|
|
13
|
+
|
|
14
|
+
def To(self, target_type: str, target_id: str) -> 'SendDSL':
|
|
15
|
+
return self.__class__(self._adapter, target_type, target_id)
|
|
16
|
+
|
|
17
|
+
def __getattr__(self, name: str):
|
|
18
|
+
def wrapper(*args, **kwargs):
|
|
19
|
+
return asyncio.create_task(
|
|
20
|
+
self._adapter._real_send(
|
|
21
|
+
target_type=self._target_type,
|
|
22
|
+
target_id=self._target_id,
|
|
23
|
+
action=name,
|
|
24
|
+
data={
|
|
25
|
+
"args": args,
|
|
26
|
+
"kwargs": kwargs
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
return wrapper
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class BaseAdapter:
|
|
34
|
+
def __init__(self, sdk):
|
|
35
|
+
self.sdk = sdk
|
|
36
|
+
self._handlers = defaultdict(list)
|
|
37
|
+
self._middlewares = []
|
|
38
|
+
|
|
39
|
+
# 检测是否有 Send 子类定义
|
|
40
|
+
if not hasattr(self.__class__, 'Send') or not issubclass(self.__class__.Send, SendDSL):
|
|
41
|
+
raise TypeError(f"{self.__class__.__name__} 必须定义 Send 嵌套类并继承 SendDSL")
|
|
42
|
+
|
|
43
|
+
# 绑定当前适配器的 Send 实例
|
|
44
|
+
self.Send = self.__class__.Send(self)
|
|
45
|
+
|
|
46
|
+
def on(self, event_type: str):
|
|
47
|
+
def decorator(func: Callable):
|
|
48
|
+
@functools.wraps(func)
|
|
49
|
+
async def wrapper(*args, **kwargs):
|
|
50
|
+
return await func(*args, **kwargs)
|
|
51
|
+
self._handlers[event_type].append(wrapper)
|
|
52
|
+
return wrapper
|
|
53
|
+
return decorator
|
|
54
|
+
|
|
55
|
+
def middleware(self, func: Callable):
|
|
56
|
+
self._middlewares.append(func)
|
|
57
|
+
return func
|
|
58
|
+
|
|
59
|
+
async def call_api(self, endpoint: str, **params):
|
|
60
|
+
raise NotImplementedError
|
|
61
|
+
|
|
62
|
+
async def start(self):
|
|
63
|
+
raise NotImplementedError
|
|
64
|
+
|
|
65
|
+
async def shutdown(self):
|
|
66
|
+
raise NotImplementedError
|
|
67
|
+
|
|
68
|
+
async def emit(self, event_type: str, data: Any):
|
|
69
|
+
for middleware in self._middlewares:
|
|
70
|
+
data = await middleware(data)
|
|
71
|
+
|
|
72
|
+
for handler in self._handlers.get(event_type, []):
|
|
73
|
+
await handler(data)
|
|
74
|
+
|
|
75
|
+
async def send(self, target_type: str, target_id: str, message: Any, **kwargs):
|
|
76
|
+
method_name = kwargs.pop("method", "Text")
|
|
77
|
+
method = getattr(self.Send.To(target_type, target_id), method_name, None)
|
|
78
|
+
if not method:
|
|
79
|
+
raise AttributeError(f"未找到 {method_name} 方法,请确保已在 Send 类中定义")
|
|
80
|
+
return await method(text=message, **kwargs)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class AdapterManager:
|
|
84
|
+
def __init__(self):
|
|
85
|
+
self._adapters: Dict[str, BaseAdapter] = {}
|
|
86
|
+
|
|
87
|
+
def register(self, platform: str, adapter_class: Type[BaseAdapter]) -> bool:
|
|
88
|
+
if not issubclass(adapter_class, BaseAdapter):
|
|
89
|
+
raise TypeError("适配器必须继承自BaseAdapter")
|
|
90
|
+
from . import sdk
|
|
91
|
+
self._adapters[platform] = adapter_class(sdk)
|
|
92
|
+
return True
|
|
93
|
+
|
|
94
|
+
async def startup(self, platforms: List[str] = None):
|
|
95
|
+
if platforms is None:
|
|
96
|
+
platforms = self._adapters.keys()
|
|
97
|
+
|
|
98
|
+
for platform in platforms:
|
|
99
|
+
if platform not in self._adapters:
|
|
100
|
+
raise ValueError(f"平台 {platform} 未注册")
|
|
101
|
+
adapter = self._adapters[platform]
|
|
102
|
+
asyncio.create_task(self._run_adapter(adapter, platform))
|
|
103
|
+
|
|
104
|
+
async def _run_adapter(self, adapter: BaseAdapter, platform: str):
|
|
105
|
+
from . import sdk
|
|
106
|
+
retry_count = 0
|
|
107
|
+
max_retry = 3
|
|
108
|
+
while retry_count < max_retry:
|
|
109
|
+
try:
|
|
110
|
+
await adapter.start()
|
|
111
|
+
break
|
|
112
|
+
except Exception as e:
|
|
113
|
+
retry_count += 1
|
|
114
|
+
sdk.logger.error(f"平台 {platform} 启动失败(第{retry_count}次重试): {e}")
|
|
115
|
+
try:
|
|
116
|
+
await adapter.stop()
|
|
117
|
+
except Exception as stop_err:
|
|
118
|
+
sdk.logger.warning(f"停止适配器失败: {stop_err}")
|
|
119
|
+
|
|
120
|
+
if retry_count >= max_retry:
|
|
121
|
+
sdk.logger.critical(f"平台 {platform} 达到最大重试次数,放弃重启")
|
|
122
|
+
sdk.raiserr.AdapterStartFailedError(f"平台 {platform} 适配器无法重写启动: {e}")
|
|
123
|
+
|
|
124
|
+
async def shutdown(self):
|
|
125
|
+
for adapter in self._adapters.values():
|
|
126
|
+
await adapter.shutdown()
|
|
127
|
+
|
|
128
|
+
def get(self, platform: str) -> BaseAdapter:
|
|
129
|
+
return self._adapters.get(platform)
|
|
130
|
+
|
|
131
|
+
def __getattr__(self, platform: str) -> BaseAdapter:
|
|
132
|
+
if platform not in self._adapters:
|
|
133
|
+
raise AttributeError(f"平台 {platform} 的适配器未注册")
|
|
134
|
+
return self._adapters[platform]
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def platforms(self) -> list:
|
|
138
|
+
return list(self._adapters.keys())
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
adapter = AdapterManager()
|
|
142
|
+
adapter.SendDSL = SendDSL
|
|
143
|
+
adapterbase = BaseAdapter()
|
|
@@ -48,7 +48,8 @@ class EnvManager:
|
|
|
48
48
|
self._init_db()
|
|
49
49
|
return self.get(key, default)
|
|
50
50
|
else:
|
|
51
|
-
|
|
51
|
+
from . import sdk
|
|
52
|
+
sdk.logger.error(f"数据库操作错误: {e}")
|
|
52
53
|
|
|
53
54
|
def get_all_keys(self) -> list:
|
|
54
55
|
with sqlite3.connect(self.db_path) as conn:
|
|
@@ -92,6 +93,7 @@ class EnvManager:
|
|
|
92
93
|
try:
|
|
93
94
|
return self.get(key)
|
|
94
95
|
except KeyError:
|
|
95
|
-
|
|
96
|
+
from . import sdk
|
|
97
|
+
sdk.logger.error(f"配置项 {key} 不存在")
|
|
96
98
|
|
|
97
99
|
env = EnvManager()
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import traceback
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
5
|
+
class Error:
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self._types = {}
|
|
8
|
+
|
|
9
|
+
def register(self, name, doc="", base=Exception):
|
|
10
|
+
if name not in self._types:
|
|
11
|
+
err_cls = type(name, (base,), {"__doc__": doc})
|
|
12
|
+
self._types[name] = err_cls
|
|
13
|
+
return self._types[name]
|
|
14
|
+
|
|
15
|
+
def __getattr__(self, name):
|
|
16
|
+
def raiser(msg, exit=False):
|
|
17
|
+
from .logger import logger
|
|
18
|
+
err_cls = self._types.get(name) or self.register(name)
|
|
19
|
+
exc = err_cls(msg)
|
|
20
|
+
|
|
21
|
+
red = '\033[91m'
|
|
22
|
+
reset = '\033[0m'
|
|
23
|
+
|
|
24
|
+
logger.error(f"{red}{name}: {msg} | {err_cls.__doc__}{reset}")
|
|
25
|
+
logger.error(f"{red}{ ''.join(traceback.format_stack()) }{reset}")
|
|
26
|
+
|
|
27
|
+
if exit:
|
|
28
|
+
raise exc
|
|
29
|
+
return raiser
|
|
30
|
+
|
|
31
|
+
def info(self, name: str = None):
|
|
32
|
+
result = {}
|
|
33
|
+
for err_name, err_cls in self._types.items():
|
|
34
|
+
result[err_name] = {
|
|
35
|
+
"type": err_name,
|
|
36
|
+
"doc": getattr(err_cls, "__doc__", ""),
|
|
37
|
+
"class": err_cls,
|
|
38
|
+
}
|
|
39
|
+
if name is None:
|
|
40
|
+
return result
|
|
41
|
+
err_cls = self._types.get(name)
|
|
42
|
+
if not err_cls:
|
|
43
|
+
return None
|
|
44
|
+
return {
|
|
45
|
+
"type": name,
|
|
46
|
+
"doc": getattr(err_cls, "__doc__", ""),
|
|
47
|
+
"class": err_cls,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
raiserr = Error()
|
|
51
|
+
|
|
52
|
+
# 全局异常处理器
|
|
53
|
+
def global_exception_handler(exc_type, exc_value, exc_traceback):
|
|
54
|
+
from .logger import logger
|
|
55
|
+
error_message = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback))
|
|
56
|
+
logger.error(f"未处理的异常被捕获:\n{error_message}")
|
|
57
|
+
raiserr.CaughtExternalError(
|
|
58
|
+
f"检测到外部异常,请优先使用 sdk.raiserr 抛出错误。\n原始异常: {exc_type.__name__}: {exc_value}\nTraceback:\n{error_message}"
|
|
59
|
+
)
|
|
60
|
+
sys.excepthook = global_exception_handler
|
|
61
|
+
|
|
62
|
+
def async_exception_handler(loop, context):
|
|
63
|
+
from .logger import logger
|
|
64
|
+
exception = context.get('exception')
|
|
65
|
+
message = context.get('message', 'Async error')
|
|
66
|
+
if exception:
|
|
67
|
+
tb = ''.join(traceback.format_exception(type(exception), exception, exception.__traceback__))
|
|
68
|
+
logger.error(f"异步任务异常: {message}\n{tb}")
|
|
69
|
+
raiserr.CaughtExternalError(
|
|
70
|
+
f"检测到异步任务异常,请优先使用 sdk.raiserr 抛出错误。\n原始异常: {type(exception).__name__}: {exception}\nTraceback:\n{tb}"
|
|
71
|
+
)
|
|
72
|
+
else:
|
|
73
|
+
logger.warning(f"异步任务警告: {message}")
|
|
74
|
+
asyncio.get_event_loop().set_exception_handler(async_exception_handler)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import time
|
|
2
2
|
import asyncio
|
|
3
3
|
import functools
|
|
4
|
+
import traceback
|
|
4
5
|
from concurrent.futures import ThreadPoolExecutor
|
|
5
6
|
from collections import defaultdict, deque
|
|
6
7
|
|
|
@@ -23,7 +24,8 @@ def topological_sort(elements, dependencies, error):
|
|
|
23
24
|
if in_degree[neighbor] == 0:
|
|
24
25
|
queue.append(neighbor)
|
|
25
26
|
if len(sorted_list) != len(elements):
|
|
26
|
-
|
|
27
|
+
from . import sdk
|
|
28
|
+
sdk.logger.error(f"Topological sort failed: {sorted_list} vs {elements}")
|
|
27
29
|
return sorted_list
|
|
28
30
|
|
|
29
31
|
def ExecAsync(async_func, *args, **kwargs):
|
|
@@ -44,7 +46,14 @@ def run_in_executor(func):
|
|
|
44
46
|
@functools.wraps(func)
|
|
45
47
|
async def wrapper(*args, **kwargs):
|
|
46
48
|
loop = asyncio.get_event_loop()
|
|
47
|
-
|
|
49
|
+
try:
|
|
50
|
+
return await loop.run_in_executor(None, lambda: func(*args, **kwargs))
|
|
51
|
+
except Exception as e:
|
|
52
|
+
from . import sdk
|
|
53
|
+
sdk.logger.error(f"线程内发生未处理异常:\n{''.join(traceback.format_exc())}")
|
|
54
|
+
sdk.raiserr.CaughtExternalError(
|
|
55
|
+
f"检测到线程内异常,请优先使用 sdk.raiserr 抛出错误。\n原始异常: {type(e).__name__}: {e}"
|
|
56
|
+
)
|
|
48
57
|
return wrapper
|
|
49
58
|
|
|
50
59
|
def retry(max_attempts=3, delay=1):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ErisPulse
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.16
|
|
4
4
|
Summary: ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。
|
|
5
5
|
Author-email: "艾莉丝·格雷拉特(WSu2059)" <wsu2059@qq.com>, runoneall <runoobsteve@gmail.com>
|
|
6
6
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ErisPulse
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.16
|
|
4
4
|
Summary: ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。
|
|
5
5
|
Author-email: "艾莉丝·格雷拉特(WSu2059)" <wsu2059@qq.com>, runoneall <runoobsteve@gmail.com>
|
|
6
6
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import functools
|
|
2
|
-
import asyncio
|
|
3
|
-
from typing import Callable, Any, Dict, List, Type
|
|
4
|
-
from collections import defaultdict
|
|
5
|
-
|
|
6
|
-
class BaseAdapter:
|
|
7
|
-
def __init__(self):
|
|
8
|
-
self._handlers = defaultdict(list)
|
|
9
|
-
self._middlewares = []
|
|
10
|
-
|
|
11
|
-
def on(self, event_type: str):
|
|
12
|
-
def decorator(func: Callable):
|
|
13
|
-
@functools.wraps(func)
|
|
14
|
-
async def wrapper(*args, **kwargs):
|
|
15
|
-
return await func(*args, **kwargs)
|
|
16
|
-
self._handlers[event_type].append(wrapper)
|
|
17
|
-
return wrapper
|
|
18
|
-
return decorator
|
|
19
|
-
|
|
20
|
-
def middleware(self, func: Callable):
|
|
21
|
-
self._middlewares.append(func)
|
|
22
|
-
return func
|
|
23
|
-
|
|
24
|
-
async def send(self, target: Any, message: Any, **kwargs):
|
|
25
|
-
raise NotImplementedError
|
|
26
|
-
|
|
27
|
-
async def call_api(self, endpoint: str, **params):
|
|
28
|
-
raise NotImplementedError
|
|
29
|
-
|
|
30
|
-
async def emit(self, event_type: str, data: Any):
|
|
31
|
-
for middleware in self._middlewares:
|
|
32
|
-
data = await middleware(data)
|
|
33
|
-
|
|
34
|
-
for handler in self._handlers.get(event_type, []):
|
|
35
|
-
await handler(data)
|
|
36
|
-
|
|
37
|
-
class AdapterManager:
|
|
38
|
-
def __init__(self):
|
|
39
|
-
self._adapters: Dict[str, BaseAdapter] = {}
|
|
40
|
-
|
|
41
|
-
def register(self, platform: str, adapter_class: Type[BaseAdapter]) -> bool:
|
|
42
|
-
if not issubclass(adapter_class, BaseAdapter):
|
|
43
|
-
raise TypeError("适配器必须继承自BaseAdapter")
|
|
44
|
-
from . import sdk
|
|
45
|
-
self._adapters[platform] = adapter_class(sdk)
|
|
46
|
-
return True
|
|
47
|
-
|
|
48
|
-
async def startup(self, platforms: List[str] = None):
|
|
49
|
-
if platforms is None:
|
|
50
|
-
platforms = self._adapters.keys()
|
|
51
|
-
|
|
52
|
-
for platform in platforms:
|
|
53
|
-
if platform not in self._adapters:
|
|
54
|
-
raise ValueError(f"平台 {platform} 未注册")
|
|
55
|
-
adapter = self._adapters[platform]
|
|
56
|
-
asyncio.create_task(self._run_adapter(adapter, platform))
|
|
57
|
-
|
|
58
|
-
async def _run_adapter(self, adapter: BaseAdapter, platform: str):
|
|
59
|
-
try:
|
|
60
|
-
await adapter.start()
|
|
61
|
-
except Exception as e:
|
|
62
|
-
self.logger.error(f"平台 {platform} 停止时遇到了错误: {e}")
|
|
63
|
-
|
|
64
|
-
async def shutdown(self):
|
|
65
|
-
for adapter in self._adapters.values():
|
|
66
|
-
await adapter.shutdown()
|
|
67
|
-
|
|
68
|
-
def get(self, platform: str) -> BaseAdapter:
|
|
69
|
-
return self._adapters.get(platform)
|
|
70
|
-
|
|
71
|
-
def __getattr__(self, platform: str) -> BaseAdapter:
|
|
72
|
-
if platform not in self._adapters:
|
|
73
|
-
raise AttributeError(f"平台 {platform} 的适配器未注册")
|
|
74
|
-
return self._adapters[platform]
|
|
75
|
-
|
|
76
|
-
@property
|
|
77
|
-
def platforms(self) -> list:
|
|
78
|
-
return list(self._adapters.keys())
|
|
79
|
-
|
|
80
|
-
adapter = AdapterManager()
|
|
81
|
-
adapterbase = BaseAdapter
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import traceback
|
|
3
|
-
|
|
4
|
-
class Error:
|
|
5
|
-
def __init__(self):
|
|
6
|
-
self._types = {}
|
|
7
|
-
|
|
8
|
-
def register(self, name, doc="", base=Exception):
|
|
9
|
-
if name not in self._types:
|
|
10
|
-
err_cls = type(name, (base,), {"__doc__": doc})
|
|
11
|
-
self._types[name] = err_cls
|
|
12
|
-
return self._types[name]
|
|
13
|
-
|
|
14
|
-
def __getattr__(self, name):
|
|
15
|
-
def raiser(msg, exit=False):
|
|
16
|
-
from .logger import logger
|
|
17
|
-
err_cls = self._types.get(name) or self.register(name)
|
|
18
|
-
exc = err_cls(msg)
|
|
19
|
-
logger.error(f"{name}: {msg} | {err_cls.__doc__}")
|
|
20
|
-
logger.error("".join(traceback.format_stack()))
|
|
21
|
-
if exit:
|
|
22
|
-
raise exc
|
|
23
|
-
return raiser
|
|
24
|
-
|
|
25
|
-
def info(self, name: str = None):
|
|
26
|
-
result = {}
|
|
27
|
-
for err_name, err_cls in self._types.items():
|
|
28
|
-
result[err_name] = {
|
|
29
|
-
"type": err_name,
|
|
30
|
-
"doc": getattr(err_cls, "__doc__", ""),
|
|
31
|
-
"class": err_cls,
|
|
32
|
-
}
|
|
33
|
-
if name is None:
|
|
34
|
-
return result
|
|
35
|
-
err_cls = self._types.get(name)
|
|
36
|
-
if not err_cls:
|
|
37
|
-
return None
|
|
38
|
-
return {
|
|
39
|
-
"type": name,
|
|
40
|
-
"doc": getattr(err_cls, "__doc__", ""),
|
|
41
|
-
"class": err_cls,
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
raiserr = Error()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|