yikart/AiToEarn · error · AppException

AiCallFailed

AiCallFailed

Error message

AiCallFailed

What it means

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.

Source

Thrown at project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/libs/volcengine/services/base.service.ts:60

      serviceName: 'vod',
    })
  }

  /**
   * 检查 API 响应中的错误并抛出异常
   */
  protected checkApiResponseError<T>(
    response: OpenApiResponse<T>,
    operation: string,
    requestData?: unknown,
  ): asserts response is OpenApiResponse<T> & { Result: T } {
    if (response.ResponseMetadata?.Error) {
      const error = response.ResponseMetadata.Error
      this.logger.error(
        { error, requestData },
        `${operation} failed: ${error.Code || 'Unknown'} - ${error.Message}`,
      )
      throw new AppException(ResponseCode.AiCallFailed, {
        code: error.Code || 'Unknown',
        message: error.Message,
      })
    }

    if (!response.Result) {
      this.logger.error({ requestData }, `${operation} returned no result`)
      throw new AppException(ResponseCode.AiCallFailed, {
        message: typeof response === 'string' ? response : 'No result returned',
      })
    }
  }
}

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Read the nested error.Code/error.Message from the thrown AppException data to get the actual Volcengine failure (e.g. InvalidAccessKey, Throttling)
  2. Verify Volcengine AK/SK credentials and that the account has the corresponding service enabled
  3. Validate request parameters (model name, action, region) against the current Volcengine API docs
  4. Implement retry with backoff for throttling-type codes; do not retry permanent codes like auth errors

Example fix

// before
catch (e) { logger.error(e.message) } // logs only 'AiCallFailed'
// after
catch (e) {
  if (e instanceof AppException) logger.error({ providerCode: e.data?.code, providerMessage: e.data?.message }, 'volcengine failure')
  throw e
}
Defensive patterns

Strategy: retry

Validate before calling

function assertVolcParams(p: { model?: string, action?: string, region?: string }) {
  if (!p.model) throw new Error('volcengine model is required')
  if (!p.region) throw new Error('volcengine region is required')
}

Type guard

function hasVolcError(data: unknown): data is { code: string, message: string } {
  return typeof data === 'object' && data !== null && 'code' in data && 'message' in data
}

Try / catch

try {
  await volcengineService.submitAideoTaskAsync(req)
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.AiCallFailed && hasVolcError(e.data)) {
    const { code, message } = e.data
    if (/throttl|limit/i.test(code)) return retryWithBackoff(() => submit(req))
    throw new BadGatewayException(`Volcengine ${code}: ${message}`)
  }
  throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/d938722987f2c6f7. Report an issue: GitHub.