yikart/AiToEarn · error · AppException
ChannelPlatformApiFailed
ChannelPlatformApiFailed
Error message
ResponseCode.ChannelPlatformApiFailed
What it means
createQrCode calls Douyin's mini-app QR-code HTTP API and throws ChannelPlatformApiFailed when the response succeeds but data.data.img is missing. It represents an upstream Douyin API response that lacks the expected image field.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/douyin/douyin-miniapp.service.ts:76
const response = await this.http.post<DouyinMiniAppQrCodeResponse>(
this.endpoints.qrCode,
{
app_name: options.appName,
appid: miniApp.clientId,
path: options.path,
width: options.width,
is_circle_code: options.isCircleCode,
},
{
headers: {
'Content-Type': 'application/json',
'access-token': accessToken,
},
},
)
const img = response.data.data?.img
if (!img) {
throw new AppException(ResponseCode.ChannelPlatformApiFailed, { platform: AccountType.Douyin, field: 'img', reasonCode: 'missing_platform_field' })
}
return img
}
async code2Session(code: string): Promise<DouyinMiniAppSessionInfo> {
const miniApp = this.miniAppConfig
const response = await this.http.post<DouyinMiniAppCode2SessionResponse>(
this.endpoints.code2Session,
{
appid: miniApp.clientId,
secret: miniApp.clientSecret,
code,
},
{
headers: {
'Content-Type': 'application/json',
},View on GitHub (pinned to d3aa8bea5b)
Solutions
- Log the full Douyin response body to see any embedded error code before the img check
- Verify the QR generation request params and accessToken permissions against the Douyin docs
- Retry after backoff if it's transient; otherwise check the Douyin open-platform console for quota/permission issues
Example fix
// before
const img = response.data.data?.img
if (!img) {
throw new AppException(ResponseCode.ChannelPlatformApiFailed, { platform: AccountType.Douyin, field: 'img', reasonCode: 'missing_platform_field' })
}
// after
const img = response.data.data?.img
if (!img) {
this.logger.warn(`douyin qr response: ${JSON.stringify(response.data)}`)
throw new AppException(ResponseCode.ChannelPlatformApiFailed, { platform: AccountType.Douyin, field: 'img', reasonCode: 'missing_platform_field', body: response.data })
} Defensive patterns
Strategy: retry
Validate before calling
if (!accessToken || accessToken.length === 0) {
throw new Error('Cannot create Douyin QR code without an access token')
} Type guard
function hasQrImage(res: { data?: { data?: { img?: unknown } } }): res is { data: { data: { img: string } } } {
return typeof res.data?.data?.img === 'string' && res.data.data.img.length > 0
} Try / catch
try {
const img = await service.createQrCode(accessToken, params)
} catch (e) {
if (e instanceof AppException && e.code === 'ChannelPlatformApiFailed') {
logger.warn('douyin qr response missing img; inspecting upstream body', { detail: e.details })
// backoff and retry, or fall back to another QR source
} else throw e
} Prevention
- Log the full upstream response body whenever an expected field is missing
- Refresh the access token before QR generation if it is near expiry
- Add retries with exponential backoff for transient Douyin API issues
- Monitor Douyin status/quota for the mini-app
When it happens
Trigger: Calling createQrCode with a valid accessToken when Douyin returns a 200 whose body has no data.img (e.g. Douyin-side error payload, rate limit encoded in body, or invalid request params Douyin silently ignores).
Common situations: Douyin API partial outage, mini-app QR generation quota exceeded, wrong scene/content params, or accessToken valid but lacking permission for QR generation.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/28471b09bc08d06b.
Report an issue: GitHub.