{"record":{"id":"d938722987f2c6f7","repo":"yikart/AiToEarn","slug":"aicallfailed-d93872","errorCode":"AiCallFailed","errorMessage":"AiCallFailed","messagePattern":"AiCallFailed","errorType":"error_code","errorClass":"AppException","httpStatus":400,"severity":"error","filePath":"project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/libs/volcengine/services/base.service.ts","lineNumber":60,"sourceCode":"      serviceName: 'vod',\n    })\n  }\n\n  /**\n   * 检查 API 响应中的错误并抛出异常\n   */\n  protected checkApiResponseError<T>(\n    response: OpenApiResponse<T>,\n    operation: string,\n    requestData?: unknown,\n  ): asserts response is OpenApiResponse<T> & { Result: T } {\n    if (response.ResponseMetadata?.Error) {\n      const error = response.ResponseMetadata.Error\n      this.logger.error(\n        { error, requestData },\n        `${operation} failed: ${error.Code || 'Unknown'} - ${error.Message}`,\n      )\n      throw new AppException(ResponseCode.AiCallFailed, {\n        code: error.Code || 'Unknown',\n        message: error.Message,\n      })\n    }\n\n    if (!response.Result) {\n      this.logger.error({ requestData }, `${operation} returned no result`)\n      throw new AppException(ResponseCode.AiCallFailed, {\n        message: typeof response === 'string' ? response : 'No result returned',\n      })\n    }\n  }\n}\n","sourceCodeStart":42,"sourceCodeEnd":74,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/libs/volcengine/services/base.service.ts#L42-L74","documentation":"checkApiResponseError is the shared guard for all Volcengine service responses. When ResponseMetadata.Error is present it logs the error and throws AppException(AiCallFailed, { code: error.Code, message: error.Message }). The provider-side Volcengine error Code/Message are preserved in the exception data, so the meaningful diagnostics are there, not in the generic 'AiCallFailed' message.","triggerScenarios":"Any Volcengine API call returning an error envelope: invalid API keys/credentials (AK/SK), expired signature, throttling/quota exceeded, invalid parameters (bad model id, unsupported region/action), or service-side failures — raised from submitAideoTaskAsync, getAideoTaskResult, submitDirectEditTaskAsync, getDirectEditResult, createDramaRecapTask, uploadMediaByUrl.","commonSituations":"Wrong or rotated Volcengine credentials; account not enabled for the specific capability; rate limiting under burst load; parameter renames after Volcengine API version updates; region mismatch.","solutions":["Read the nested error.Code/error.Message from the thrown AppException data to get the actual Volcengine failure (e.g. InvalidAccessKey, Throttling)","Verify Volcengine AK/SK credentials and that the account has the corresponding service enabled","Validate request parameters (model name, action, region) against the current Volcengine API docs","Implement retry with backoff for throttling-type codes; do not retry permanent codes like auth errors"],"exampleFix":"// before\ncatch (e) { logger.error(e.message) } // logs only 'AiCallFailed'\n// after\ncatch (e) {\n  if (e instanceof AppException) logger.error({ providerCode: e.data?.code, providerMessage: e.data?.message }, 'volcengine failure')\n  throw e\n}","handlingStrategy":"retry","validationCode":"function assertVolcParams(p: { model?: string, action?: string, region?: string }) {\n  if (!p.model) throw new Error('volcengine model is required')\n  if (!p.region) throw new Error('volcengine region is required')\n}","typeGuard":"function hasVolcError(data: unknown): data is { code: string, message: string } {\n  return typeof data === 'object' && data !== null && 'code' in data && 'message' in data\n}","tryCatchPattern":"try {\n  await volcengineService.submitAideoTaskAsync(req)\n} catch (e) {\n  if (e instanceof AppException && e.code === ResponseCode.AiCallFailed && hasVolcError(e.data)) {\n    const { code, message } = e.data\n    if (/throttl|limit/i.test(code)) return retryWithBackoff(() => submit(req))\n    throw new BadGatewayException(`Volcengine ${code}: ${message}`)\n  }\n  throw e\n}","preventionTips":["Log the nested error.Code/Message — they contain the actionable provider reason","Rotate/verify AK/SK credentials before blaming the service","Retry only throttling-type codes; auth/param codes are permanent","Validate model/action/region against the current Volcengine API docs after version updates"],"tags":["volcengine","api","provider-error"],"backgroundTag":"provider-api-error","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}