mirror of
				https://github.com/nonebot/nonebot2.git
				synced 2025-10-26 12:36:40 +00:00 
			
		
		
		
	✨ support for mock api result (resolve #605)
This commit is contained in:
		| @@ -43,11 +43,22 @@ sidebarDepth: 0 | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## _exception_ `IgnoredException` | ## _exception_ `ProcessException` | ||||||
|  |  | ||||||
| 基类:`nonebot.exception.NoneBotException` | 基类:`nonebot.exception.NoneBotException` | ||||||
|  |  | ||||||
|  |  | ||||||
|  | * **说明** | ||||||
|  |  | ||||||
|  |     事件处理过程中发生的异常基类。 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## _exception_ `IgnoredException` | ||||||
|  |  | ||||||
|  | 基类:`nonebot.exception.ProcessException` | ||||||
|  |  | ||||||
|  |  | ||||||
| * **说明** | * **说明** | ||||||
|  |  | ||||||
|     指示 NoneBot 应该忽略该事件。可由 PreProcessor 抛出。 |     指示 NoneBot 应该忽略该事件。可由 PreProcessor 抛出。 | ||||||
| @@ -61,9 +72,27 @@ sidebarDepth: 0 | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## _exception_ `MockApiException` | ||||||
|  |  | ||||||
|  | 基类:`nonebot.exception.ProcessException` | ||||||
|  |  | ||||||
|  |  | ||||||
|  | * **说明** | ||||||
|  |  | ||||||
|  |     指示 NoneBot 阻止本次 API 调用或修改本次调用返回值,并返回自定义内容。可由 api hook 抛出。 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | * **参数** | ||||||
|  |  | ||||||
|  |      | ||||||
|  |     * `result`: 返回的内容 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## _exception_ `StopPropagation` | ## _exception_ `StopPropagation` | ||||||
|  |  | ||||||
| 基类:`nonebot.exception.NoneBotException` | 基类:`nonebot.exception.ProcessException` | ||||||
|  |  | ||||||
|  |  | ||||||
| * **说明** | * **说明** | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Any, Set, Tuple, Union, Optional | |||||||
|  |  | ||||||
| from nonebot.log import logger | from nonebot.log import logger | ||||||
| from nonebot.config import Config | from nonebot.config import Config | ||||||
|  | from nonebot.exception import MockApiException | ||||||
| from nonebot.typing import T_CalledAPIHook, T_CallingAPIHook | from nonebot.typing import T_CalledAPIHook, T_CallingAPIHook | ||||||
| from nonebot.drivers import Driver, HTTPResponse, HTTPConnection | from nonebot.drivers import Driver, HTTPResponse, HTTPConnection | ||||||
|  |  | ||||||
| @@ -137,24 +138,33 @@ class Bot(abc.ABC): | |||||||
|             await bot.call_api("send_msg", message="hello world") |             await bot.call_api("send_msg", message="hello world") | ||||||
|             await bot.send_msg(message="hello world") |             await bot.send_msg(message="hello world") | ||||||
|         """ |         """ | ||||||
|  |  | ||||||
|  |         result: Any = None | ||||||
|  |         skip_calling_api: bool = False | ||||||
|  |         exception: Optional[Exception] = None | ||||||
|  |  | ||||||
|         coros = list(map(lambda x: x(self, api, data), self._calling_api_hook)) |         coros = list(map(lambda x: x(self, api, data), self._calling_api_hook)) | ||||||
|         if coros: |         if coros: | ||||||
|             try: |             try: | ||||||
|                 logger.debug("Running CallingAPI hooks...") |                 logger.debug("Running CallingAPI hooks...") | ||||||
|                 await asyncio.gather(*coros) |                 await asyncio.gather(*coros) | ||||||
|  |             except MockApiException as e: | ||||||
|  |                 skip_calling_api = True | ||||||
|  |                 result = e.result | ||||||
|  |                 logger.debug( | ||||||
|  |                     f"Calling API {api} is cancelled. Return {result} instead." | ||||||
|  |                 ) | ||||||
|             except Exception as e: |             except Exception as e: | ||||||
|                 logger.opt(colors=True, exception=e).error( |                 logger.opt(colors=True, exception=e).error( | ||||||
|                     "<r><bg #f8bbd0>Error when running CallingAPI hook. " |                     "<r><bg #f8bbd0>Error when running CallingAPI hook. " | ||||||
|                     "Running cancelled!</bg #f8bbd0></r>" |                     "Running cancelled!</bg #f8bbd0></r>" | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
|         exception = None |         if not skip_calling_api: | ||||||
|         result = None |             try: | ||||||
|  |                 result = await self._call_api(api, **data) | ||||||
|         try: |             except Exception as e: | ||||||
|             result = await self._call_api(api, **data) |                 exception = e | ||||||
|         except Exception as e: |  | ||||||
|             exception = e |  | ||||||
|  |  | ||||||
|         coros = list( |         coros = list( | ||||||
|             map(lambda x: x(self, exception, api, data, result), self._called_api_hook) |             map(lambda x: x(self, exception, api, data, result), self._called_api_hook) | ||||||
| @@ -163,6 +173,11 @@ class Bot(abc.ABC): | |||||||
|             try: |             try: | ||||||
|                 logger.debug("Running CalledAPI hooks...") |                 logger.debug("Running CalledAPI hooks...") | ||||||
|                 await asyncio.gather(*coros) |                 await asyncio.gather(*coros) | ||||||
|  |             except MockApiException as e: | ||||||
|  |                 result = e.result | ||||||
|  |                 logger.debug( | ||||||
|  |                     f"Calling API {api} result is mocked. Return {result} instead." | ||||||
|  |                 ) | ||||||
|             except Exception as e: |             except Exception as e: | ||||||
|                 logger.opt(colors=True, exception=e).error( |                 logger.opt(colors=True, exception=e).error( | ||||||
|                     "<r><bg #f8bbd0>Error when running CalledAPI hook. " |                     "<r><bg #f8bbd0>Error when running CalledAPI hook. " | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ | |||||||
| 这些异常并非所有需要用户处理,在 NoneBot 内部运行时被捕获,并进行对应操作。 | 这些异常并非所有需要用户处理,在 NoneBot 内部运行时被捕获,并进行对应操作。 | ||||||
| """ | """ | ||||||
|  |  | ||||||
| from typing import Optional | from typing import Any, Optional | ||||||
|  |  | ||||||
|  |  | ||||||
| class NoneBotException(Exception): | class NoneBotException(Exception): | ||||||
| @@ -42,7 +42,15 @@ class ParserExit(NoneBotException): | |||||||
|  |  | ||||||
|  |  | ||||||
| # Processor Exception | # Processor Exception | ||||||
| class IgnoredException(NoneBotException): | class ProcessException(NoneBotException): | ||||||
|  |     """ | ||||||
|  |     :说明: | ||||||
|  |  | ||||||
|  |       事件处理过程中发生的异常基类。 | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class IgnoredException(ProcessException): | ||||||
|     """ |     """ | ||||||
|     :说明: |     :说明: | ||||||
|  |  | ||||||
| @@ -63,7 +71,28 @@ class IgnoredException(NoneBotException): | |||||||
|         return self.__repr__() |         return self.__repr__() | ||||||
|  |  | ||||||
|  |  | ||||||
| class StopPropagation(NoneBotException): | class MockApiException(ProcessException): | ||||||
|  |     """ | ||||||
|  |     :说明: | ||||||
|  |  | ||||||
|  |       指示 NoneBot 阻止本次 API 调用或修改本次调用返回值,并返回自定义内容。可由 api hook 抛出。 | ||||||
|  |  | ||||||
|  |     :参数: | ||||||
|  |  | ||||||
|  |       * ``result``: 返回的内容 | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     def __init__(self, result: Any): | ||||||
|  |         self.result = result | ||||||
|  |  | ||||||
|  |     def __repr__(self): | ||||||
|  |         return f"<ApiCancelledException, result={self.result}>" | ||||||
|  |  | ||||||
|  |     def __str__(self): | ||||||
|  |         return self.__repr__() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class StopPropagation(ProcessException): | ||||||
|     """ |     """ | ||||||
|     :说明: |     :说明: | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user