文档更新

This commit is contained in:
LuiKlee
2025-12-17 09:44:51 +08:00
parent 7fb9786241
commit 3d8e0bc26e
6 changed files with 891 additions and 36 deletions

View File

@@ -0,0 +1,395 @@
# 🔧 插件开发故障排除指南
本指南帮助你快速解决 MoFox-Bot 插件开发中的常见问题。
---
## 📋 快速诊断清单
遇到问题时,首先按照以下步骤检查:
1. ✅ 检查日志文件 `logs/app_*.jsonl`
2. ✅ 确认插件已在 `_manifest.json` 中正确配置
3. ✅ 验证你使用的是 `PlusCommand` 而不是 `BaseCommand`
4. ✅ 检查 `execute()` 方法签名是否正确
5. ✅ 确认返回值格式正确
---
## 🔴 严重问题:插件无法加载
### 错误 #1: "未检测到插件"
**症状**
- 插件目录存在,但日志中没有加载信息
- `get_plugin_components()` 返回空列表
**可能原因与解决方案**
#### ❌ 缺少 `@register_plugin` 装饰器
```python
# 错误 - 缺少装饰器
class MyPlugin(BasePlugin): # 不会被检测到
pass
# 正确 - 添加装饰器
@register_plugin # 必须添加!
class MyPlugin(BasePlugin):
pass
```
#### ❌ `plugin.py` 文件不存在或位置错误
```
plugins/
└── my_plugin/
├── _manifest.json ✅
└── plugin.py ✅ 必须在这里
```
#### ❌ `_manifest.json` 格式错误
```json
{
"manifest_version": 1,
"name": "My Plugin",
"version": "1.0.0",
"description": "插件描述",
"author": {
"name": "Your Name"
}
}
```
---
### 错误 #2: "ActionInfo.__init__() missing required argument: 'component_type'"
**症状**
```
TypeError: ActionInfo.__init__() missing 1 required positional argument: 'component_type'
```
**原因**:手动创建 `ActionInfo` 时未指定 `component_type` 参数
**解决方案**
```python
from src.plugin_system import ActionInfo, ComponentType
# ❌ 错误 - 缺少 component_type
action_info = ActionInfo(
name="my_action",
description="我的动作"
)
# ✅ 正确方法 1 - 使用自动生成(推荐)
class MyAction(BaseAction):
action_name = "my_action"
action_description = "我的动作"
def get_plugin_components(self):
return [
(MyAction.get_action_info(), MyAction) # 自动生成,推荐!
]
# ✅ 正确方法 2 - 手动指定 component_type
action_info = ActionInfo(
name="my_action",
description="我的动作",
component_type=ComponentType.ACTION # 必须指定!
)
```
---
## 🟡 命令问题:命令无响应
### 错误 #3: 命令被识别但不执行
**症状**
- 输入 `/mycommand` 后没有任何反应
- 日志显示命令已匹配但未执行
**可能原因与解决方案**
#### ❌ 使用了 `BaseCommand` 而不是 `PlusCommand`
```python
# ❌ 错误 - 使用 BaseCommand
from src.plugin_system import BaseCommand
class MyCommand(BaseCommand): # 不推荐!
command_name = "mycommand"
command_pattern = r"^/mycommand$" # 需要手动写正则
async def execute(self): # 签名错误!
pass
# ✅ 正确 - 使用 PlusCommand
from src.plugin_system import PlusCommand, CommandArgs
class MyCommand(PlusCommand): # 推荐!
command_name = "mycommand"
# 不需要 command_pattern会自动生成
async def execute(self, args: CommandArgs): # 正确签名
await self.send_text("命令执行成功")
return True, "执行了mycommand", True
```
#### ❌ `execute()` 方法签名错误
```python
# ❌ 错误的签名(缺少 args 参数)
async def execute(self) -> Tuple[bool, Optional[str], bool]:
pass
# ❌ 错误的签名(参数类型错误)
async def execute(self, args: list[str]) -> Tuple[bool, Optional[str], bool]:
pass
# ✅ 正确的签名
async def execute(self, args: CommandArgs) -> Tuple[bool, Optional[str], bool]:
await self.send_text("响应用户")
return True, "日志描述", True
```
---
### 错误 #4: 命令发送了消息但用户没收到
**症状**
- 日志显示命令执行成功
- 但用户没有收到任何消息
**原因**:在返回值中返回消息,而不是使用 `self.send_text()`
**解决方案**
```python
# ❌ 错误 - 在返回值中返回消息
async def execute(self, args: CommandArgs):
message = "这是给用户的消息"
return True, message, True # 这不会发送给用户!
# ✅ 正确 - 使用 self.send_text()
async def execute(self, args: CommandArgs):
# 发送消息给用户
await self.send_text("这是给用户的消息")
# 返回日志描述(不是用户消息)
return True, "执行了某个操作", True
```
---
### 错误 #5: "notice处理失败" 或重复消息
**症状**
- 日志中出现 "notice处理失败"
- 用户收到重复的消息
**原因**:同时使用了 `send_api.send_text()` 和返回消息
**解决方案**
```python
# ❌ 错误 - 混用不同的发送方式
from src.plugin_system.apis.chat_api import send_api
async def execute(self, args: CommandArgs):
await send_api.send_text(self.stream_id, "消息1") # 不要这样做
return True, "消息2", True # 也不要返回消息
# ✅ 正确 - 只使用 self.send_text()
async def execute(self, args: CommandArgs):
await self.send_text("这是唯一的消息") # 推荐方式
return True, "日志:执行成功", True # 仅用于日志
```
---
## 🟢 配置问题
### 错误 #6: 配置警告 "配置中不存在字空间或键"
**症状**
```
获取全局配置 plugins.my_plugin 失败: "配置中不存在字空间或键 'plugins'"
```
**这是正常的吗?**
**是的,这是正常行为!** 不需要修复。
**说明**
- 系统首先尝试从全局配置加载:`config/plugins/my_plugin/config.toml`
- 如果不存在,会自动回退到插件本地配置:`plugins/my_plugin/config.toml`
- 这个警告可以安全忽略
**如果你想消除警告**
1.`config/plugins/` 目录创建你的插件配置目录
2. 或者直接忽略 - 使用本地配置完全正常
---
## 🔧 返回值问题
### 错误 #7: 返回值格式错误
**Action 返回值** (2个元素)
```python
async def execute(self) -> Tuple[bool, str]:
await self.send_text("消息")
return True, "日志描述" # 2个元素
```
**Command 返回值** (3个元素)
```python
async def execute(self, args: CommandArgs) -> Tuple[bool, Optional[str], bool]:
await self.send_text("消息")
return True, "日志描述", True # 3个元素增加了拦截标志
```
**对比表格**
| 组件类型 | 返回值 | 元素说明 |
|----------|--------|----------|
| **Action** | `(bool, str)` | (成功标志, 日志描述) |
| **Command** | `(bool, str, bool)` | (成功标志, 日志描述, 拦截标志) |
---
## 🎯 参数解析问题
### 错误 #8: 无法获取命令参数
**症状**
- `args` 为空或不包含预期的参数
**解决方案**
```python
async def execute(self, args: CommandArgs):
# 检查是否有参数
if args.is_empty():
await self.send_text("❌ 缺少参数\n用法: /command <参数>")
return True, "缺少参数", True
# 获取原始参数字符串
raw_input = args.get_raw()
# 获取解析后的参数列表
arg_list = args.get_args()
# 获取第一个参数
first_arg = args.get_first("默认值")
# 获取指定索引的参数
second_arg = args.get_arg(1, "默认值")
# 检查标志
if args.has_flag("--verbose"):
# 处理 --verbose 模式
pass
# 获取标志的值
output = args.get_flag_value("--output", "default.txt")
```
---
## 📝 类型注解问题
### 错误 #9: IDE 报类型错误
**解决方案**:确保使用正确的类型导入
```python
from typing import Tuple, Optional, List, Type
from src.plugin_system import (
BasePlugin,
PlusCommand,
BaseAction,
CommandArgs,
ComponentInfo,
CommandInfo,
ActionInfo,
ComponentType
)
# 正确的类型注解
def get_plugin_components(self) -> List[Tuple[ComponentInfo, Type]]:
return [
(MyCommand.get_command_info(), MyCommand),
(MyAction.get_action_info(), MyAction)
]
```
---
## 🚀 性能问题
### 错误 #10: 插件响应缓慢
**可能原因**
1. **阻塞操作**:在 `execute()` 中使用了同步 I/O
2. **大量数据处理**:在主线程处理大文件或复杂计算
3. **频繁的数据库查询**:每次都查询数据库
**解决方案**
```python
import asyncio
async def execute(self, args: CommandArgs):
# ✅ 使用异步操作
result = await some_async_function()
# ✅ 对于同步操作,使用 asyncio.to_thread
result = await asyncio.to_thread(blocking_function)
# ✅ 批量数据库操作
from src.common.database.optimization.batch_scheduler import get_batch_scheduler
scheduler = get_batch_scheduler()
await scheduler.schedule_batch_insert(Model, data_list)
return True, "执行成功", True
```
---
## 📞 获取帮助
如果以上方案都无法解决你的问题:
1. **查看日志**:检查 `logs/app_*.jsonl` 获取详细错误信息
2. **查阅文档**
- [快速开始指南](./quick-start.md)
- [增强命令指南](./PLUS_COMMAND_GUIDE.md)
- [Action组件指南](./action-components.md)
3. **在线文档**https://mofox-studio.github.io/MoFox-Bot-Docs/
4. **提交 Issue**:在 GitHub 仓库提交详细的问题报告
---
## 🎓 最佳实践速查
| 场景 | 推荐做法 | 避免 |
|------|----------|------|
| 创建命令 | 使用 `PlusCommand` | ❌ 使用 `BaseCommand` |
| 发送消息 | `await self.send_text()` | ❌ 在返回值中返回消息 |
| 注册组件 | 使用 `get_action_info()` | ❌ 手动创建不带 `component_type` 的 Info |
| 参数处理 | 使用 `CommandArgs` 方法 | ❌ 手动解析字符串 |
| 异步操作 | 使用 `async/await` | ❌ 使用同步阻塞操作 |
| 配置读取 | `self.get_config()` | ❌ 硬编码配置值 |
---
**最后更新**2024-12-17
**版本**v1.0.0
有问题欢迎反馈,帮助我们改进这份指南!