yikart/AiToEarn · error · AppException
AiCallFailed
AiCallFailed
Error message
AiCallFailed
What it means
drama-recap.service.ts 的 getDramaRecapTask 查询短剧解说任务时,若响应 ResponseMetadata.Error 存在(火山引擎业务级错误,如无效任务 ID、权限、限流),则统一包装为 AiCallFailed 抛出,附原始 Code 和 Message。
Source
Thrown at project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/libs/volcengine/services/drama-recap.service.ts:79
request: QueryDramaRecapTaskRequest,
): Promise<QueryDramaRecapTaskResponse> {
const api = this.vodService.createAPI<
QueryDramaRecapTaskRequest,
QueryDramaRecapTaskResponse
>('QueryDramaRecapTask', {
Version: '2025-03-03',
method: 'GET',
contentType: 'json',
})
const response = await api(request)
// 检查 API 响应中的错误
if (response.ResponseMetadata?.Error) {
const error = response.ResponseMetadata.Error
this.logger.error(
{ error, requestData: request },
`QueryDramaRecapTask failed: ${error.Code || 'Unknown'} - ${error.Message}`,
)
throw new AppException(ResponseCode.AiCallFailed, {
code: error.Code || 'Unknown',
message: error.Message,
})
}
// 对于短剧解说任务,Result 可能为空(任务刚提交还在准备中)
// 返回一个默认的处理中状态,让上层继续轮询
if (!response.Result) {
this.logger.debug({ taskId: request.TaskId }, '[getDramaRecapTask] Result 为空,任务可能还在准备中')
return {
TaskId: request.TaskId,
Status: DramaRecapTaskStatus.Processing,
}
}
return response.Result
}
}View on GitHub (pinned to d3aa8bea5b)
Solutions
- 读取异常 data 中的 code/message(如 InvalidTaskId、SignatureDoesNotMatch),按具体错误处理。
- 核对 VolcengineConfig 中 accessKeyId/secretAccessKey 及对应服务开通状态。
- 确认 TaskId 来自 createDramaRecapTask 的返回且仍在有效期内。
- 对限流类错误(RequestLimitExceeded 等)加指数退避重试。
Example fix
// before
const res = await volcengineService.getDramaRecapTask({ TaskId })
// after
try {
const res = await volcengineService.getDramaRecapTask({ TaskId })
} catch (e) {
const code = (e as any)?.data?.code
if (code === 'RequestLimitExceeded') return retryWithBackoff()
throw e
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!taskId) throw new Error('TaskId is required')
// env check
for (const k of ['VOLC_ACCESS_KEY_ID', 'VOLC_SECRET_ACCESS_KEY']) {
if (!process.env[k]) throw new Error(`Missing env ${k}`)
} Type guard
function hasVolcengineError(r: unknown): r is { ResponseMetadata: { Error: { Code: string, Message: string } } } {
return r != null && typeof r === 'object'
&& !!(r as any).ResponseMetadata?.Error
} Try / catch
try {
const res = await getDramaRecapTask({ TaskId })
} catch (e) {
const code = (e as any)?.data?.code
if (code === 'RequestLimitExceeded') return retryWithBackoff()
if (code === 'InvalidTaskId' || code === 'ResourceNotFound') return markTaskFailed(taskId)
throw e
} Prevention
- 按异常 data.code 分支处理,而不是把所有 AiCallFailed 一律重试
- 确保 AK/SK 来自已开通短剧解说能力的账号并定期轮换
- 只查询 createDramaRecapTask 返回的 TaskId
- 对限流错误使用指数退避,避免风暴式重试
When it happens
Trigger: 调用 getDramaRecapTask(或已废弃的 queryDramaRecapTask)时火山返回带 ResponseMetadata.Error 的响应,例如 QueryDramaRecapTask 的 TaskId 不存在、AK/SK 权限不足、签名错误、配额/限流 InvalidRequest 或 InternalError。
Common situations: AK/SK 配置错误或未开通短剧解说权限;查询尚未提交成功的 TaskId;账号被限流;火山侧服务故障;任务属于其他 Region/账号。
Related errors
- AiCallFailed
- AiCallFailed
- AiCallFailed
- image_tail requires a single first frame image
- content is required
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/a1d0baa380659d12.
Report an issue: GitHub.