9.3 KiB
9.3 KiB
问题修复 - 批量任务统计计数错误 v3.6.1
📌 修复时间
2025-10-07
🐛 问题描述
现象
在批量自动化任务执行过程中,出现严重的统计错误:
统计数据异常
- 总计: 318个token
- 成功: 132个
- 失败: 0个 ❌(明显错误)
- 跳过: 0个
- 遗失: 186个token未被统计
显示矛盾
大量token卡片出现自相矛盾的显示:
- ❌ 状态标签:"已完成"(绿色)
- ❌ 显示文字:"失败名"(红色)
- 矛盾:失败的token被错误标记为"已完成"
用户反馈
-
"明明有存在失败的,没有进行wss链接的token卡片,但是总计却没有显示失败的"
-
"有大量失败的token卡片显示已完成,可能这是导致失败统计错误的关键" ✅(关键发现)
🔍 问题分析
核心问题(主要)⚠️
问题1: 子任务失败被忽略
在 executeTokenTasks 函数(第327-413行)中,存在严重逻辑错误:
} catch (error) {
console.error(` ❌ 任务失败: ${taskName}`, error.message)
// 保存错误信息
taskProgress.value[tokenId].result[taskName] = {
success: false,
error: error.message
}
// ❌ 问题:只记录错误,没有统计失败数量
// 继续执行下一个任务(单个任务失败不影响整体)
}
// ❌ 核心问题:无论上面有多少任务失败,都标记为完成
updateTaskProgress(tokenId, {
status: 'completed', // ❌ 错误!
progress: 100,
currentTask: null,
endTime: Date.now()
})
executionStats.value.success++ // ❌ 错误!计入成功
console.log(`✅ Token完成: ${token.name}`)
问题本质:
- for循环中的catch块捕获了子任务错误
- 但只是记录错误,继续执行下一个任务
- 循环结束后,无论有多少任务失败,都标记为"completed"并计入成功
- 这导致所有token都显示"已完成",即使所有子任务都失败了
次要问题
问题2: Promise异常处理不完整
在 executeBatchWithConcurrency 函数中,外层catch块未更新失败计数(已在上次提交修复)。
✅ 解决方案
修复1: 智能状态判断(核心修复)
添加失败计数和智能状态判断逻辑:
// 依次执行任务
let taskFailedCount = 0 // 🆕 记录失败的任务数量
for (let i = 0; i < tasks.length; i++) {
// ... 任务执行代码 ...
try {
const result = await executeTask(tokenId, taskName)
// ... 成功处理 ...
} catch (error) {
console.error(` ❌ 任务失败: ${taskName}`, error.message)
taskProgress.value[tokenId].result[taskName] = {
success: false,
error: error.message
}
taskFailedCount++ // 🆕 增加失败计数
}
}
// 🆕 根据任务执行情况决定最终状态
const hasAnyTaskFailed = taskFailedCount > 0
const allTasksFailed = taskFailedCount === tasks.length
if (allTasksFailed) {
// 所有任务都失败 - 标记为失败
updateTaskProgress(tokenId, {
status: 'failed',
progress: 100,
currentTask: null,
error: `所有任务执行失败 (${taskFailedCount}/${tasks.length})`,
endTime: Date.now()
})
executionStats.value.failed++
console.log(`❌ Token失败: ${token.name} (所有任务都失败)`)
} else if (hasAnyTaskFailed) {
// 部分任务失败 - 标记为部分完成(视为完成但记录错误)
updateTaskProgress(tokenId, {
status: 'completed',
progress: 100,
currentTask: null,
error: `部分任务失败 (${taskFailedCount}/${tasks.length})`,
endTime: Date.now()
})
executionStats.value.success++
console.log(`⚠️ Token部分完成: ${token.name} (${taskFailedCount}个任务失败)`)
} else {
// 所有任务成功 - 标记为完成
updateTaskProgress(tokenId, {
status: 'completed',
progress: 100,
currentTask: null,
endTime: Date.now()
})
executionStats.value.success++
console.log(`✅ Token完成: ${token.name}`)
}
修复逻辑
三种状态判断
-
所有任务失败 (
taskFailedCount === tasks.length)- 标记为
'failed' - 计入失败统计
- 记录详细错误信息
- 标记为
-
部分任务失败 (
taskFailedCount > 0)- 标记为
'completed'(视为部分完成) - 计入成功统计(因为至少完成了部分任务)
- 在error字段记录失败信息,便于查看
- 标记为
-
所有任务成功 (
taskFailedCount === 0)- 标记为
'completed' - 计入成功统计
- 标记为
设计考量
-
为什么部分失败算成功?
- 一键补差有40+个子任务
- 如果1个任务失败就算整体失败,会导致成功率过低
- 部分完成仍有价值(大部分奖励已领取)
- 通过error字段可查看具体失败了哪些任务
-
如何区分部分失败和全部成功?
- 查看token卡片的error信息
- 部分失败会显示:
部分任务失败 (3/43) - 全部成功不会有error信息
修复2: Promise异常处理补充
在外层catch中添加状态检查,避免重复计数:
.catch(error => {
console.error(`❌ Token ${tokenId} 执行失败:`, error)
// 🆕 确保失败计数被正确更新
const tokenProgress = taskProgress.value[tokenId]
if (!tokenProgress || tokenProgress.status === 'pending' || tokenProgress.status === 'executing') {
// 只有当状态还未最终确定时才更新(避免重复计数)
updateTaskProgress(tokenId, {
status: 'failed',
error: error.message,
endTime: Date.now()
})
executionStats.value.failed++
}
// 清理执行队列
const index = executing.indexOf(promise)
if (index > -1) {
executing.splice(index, 1)
}
executingTokens.value.delete(tokenId)
})
📊 修复效果对比
修复前(错误)
总计: 318
成功: 132 ← 包含了大量实际失败的token
失败: 0 ← 错误!所有失败都被误判为成功
跳过: 0
合计: 132 ← 遗失了186个token
Token显示矛盾:
- 状态:已完成(绿色)❌
- 文字:失败名(红色)❌
修复后(正确)
总计: 318
成功: X ← 只包含真正成功或部分完成的token
失败: Y ← 正确统计所有任务都失败的token
跳过: 0
合计: 318 ← 完整统计
Token显示一致:
- 所有任务失败:状态=失败(红色),文字=失败名(红色)✅
- 部分任务失败:状态=已完成(绿色),error=部分任务失败 (X/43)
- 所有任务成功:状态=已完成(绿色),无错误信息
🔧 涉及文件
src/stores/batchTaskStore.js- 第327-413行:
executeTokenTasks函数(核心修复) - 第257-279行:Promise异常处理(补充修复)
- 第327-413行:
📝 测试建议
测试场景1: 所有任务失败
- 断开网络或使用无效token
- 执行批量任务
- 验证:
- ✅ token状态标记为"失败"
- ✅ 失败计数正确增加
- ✅ error显示:
所有任务执行失败 (6/6)
测试场景2: 部分任务失败
- 使用正常token,但模拟部分子任务失败
- 验证:
- ✅ token状态标记为"已完成"
- ✅ 成功计数增加
- ✅ error显示:
部分任务失败 (2/6)
测试场景3: 所有任务成功
- 使用正常token和网络
- 验证:
- ✅ token状态标记为"已完成"
- ✅ 成功计数增加
- ✅ error为空
测试场景4: 高并发混合场景
- 并发100个token(成功、部分失败、全部失败混合)
- 验证:
- ✅
成功 + 失败 + 跳过 = 总计 - ✅ 不存在"遗失"的统计
- ✅ 每个token状态与实际情况一致
- ✅
🎯 预期结果
统计准确性
- ✅ 所有token都被正确统计
- ✅
成功 + 失败 + 跳过 = 总计 - ✅ 失败计数准确反映"所有任务都失败"的token数量
- ✅ 成功计数包含"全部成功"和"部分成功"的token
显示一致性
- ✅ token状态与实际执行结果一致
- ✅ 不再出现"已完成"但显示"失败名"的矛盾
- ✅ 部分失败的token通过error字段明确标识
用户体验
- ✅ 清晰了解哪些token完全失败
- ✅ 可通过error信息查看部分失败详情
- ✅ 统计数据可信,便于决策
📌 注意事项
1. 部分失败的处理策略
- 部分失败计入"成功"是合理的设计
- 一键补差有40+个子任务,允许部分容错
- 用户可通过详情查看具体失败的子任务
2. 避免重复计数
- 通过
taskFailedCount精确统计失败数量 - 外层catch通过状态检查避免重复更新
- 确保每个token只被计入一次
3. 错误信息保留
- 所有失败都会记录详细错误信息
- 部分失败会注明失败比例
- 便于后续排查和优化
🔗 相关文档
📅 版本信息
- 版本号: v3.6.1
- 修复日期: 2025-10-07
- 问题类型: 严重Bug修复
- 优先级: 最高(影响核心统计逻辑)
- 影响范围: 所有批量任务执行