|
|
|
|
|
""" |
|
@Time : 2023/12/19 14:46 |
|
@Author : alexanderwu |
|
@File : exceptions.py |
|
""" |
|
|
|
|
|
import asyncio |
|
import functools |
|
import traceback |
|
from typing import Any, Callable, Tuple, Type, TypeVar, Union |
|
|
|
from metagpt.logs import logger |
|
|
|
ReturnType = TypeVar("ReturnType") |
|
|
|
|
|
def handle_exception( |
|
_func: Callable[..., ReturnType] = None, |
|
*, |
|
exception_type: Union[Type[Exception], Tuple[Type[Exception], ...]] = Exception, |
|
exception_msg: str = "", |
|
default_return: Any = None, |
|
) -> Callable[..., ReturnType]: |
|
"""handle exception, return default value""" |
|
|
|
def decorator(func: Callable[..., ReturnType]) -> Callable[..., ReturnType]: |
|
@functools.wraps(func) |
|
async def async_wrapper(*args: Any, **kwargs: Any) -> ReturnType: |
|
try: |
|
return await func(*args, **kwargs) |
|
except exception_type as e: |
|
logger.opt(depth=1).error( |
|
f"{e}: {exception_msg}, " |
|
f"\nCalling {func.__name__} with args: {args}, kwargs: {kwargs} " |
|
f"\nStack: {traceback.format_exc()}" |
|
) |
|
return default_return |
|
|
|
@functools.wraps(func) |
|
def sync_wrapper(*args: Any, **kwargs: Any) -> ReturnType: |
|
try: |
|
return func(*args, **kwargs) |
|
except exception_type as e: |
|
logger.opt(depth=1).error( |
|
f"Calling {func.__name__} with args: {args}, kwargs: {kwargs} failed: {e}, " |
|
f"stack: {traceback.format_exc()}" |
|
) |
|
return default_return |
|
|
|
if asyncio.iscoroutinefunction(func): |
|
return async_wrapper |
|
else: |
|
return sync_wrapper |
|
|
|
if _func is None: |
|
return decorator |
|
else: |
|
return decorator(_func) |
|
|