yikart/AiToEarn · error · DouyinPlatformException
15070
15070
Error message
{{platform}} platform API request failed What it means
DouyinMiniAppService builds its Axios client in createHttpClient with response interceptors that convert any failure into a DouyinPlatformException (ChannelPlatformException) with the '{{platform}} platform API request failed' message (code 15070). fromAxiosError handles axios rejections (network errors, 4xx/5xx) and fromPlatformResponse handles HTTP 200 bodies carrying a Douyin error code (error_code/err_no/extra.error_code). The exception records endpoint, httpStatus, platformCode, retryability, and a category, preserving the raw Douyin failure for callers.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/douyin/douyin-miniapp.service.ts:311
for (const record of orderedRecords) {
if (record.total_fans !== undefined) {
return Number(record.total_fans)
}
}
return undefined
}
private createHttpClient(): AxiosInstance {
const http = axios.create({ timeout: 10000 })
http.interceptors.response.use(
(response) => {
if (DouyinPlatformException.hasPlatformError(response)) {
throw DouyinPlatformException.fromPlatformResponse(response)
}
return response
},
(error: AxiosError<DouyinPlatformResponseBody>) => {
throw DouyinPlatformException.fromAxiosError(error)
},
)
return http
}
private get miniAppConfig(): DouyinMiniAppConfigValue {
const miniApp = this.cfg.miniApp
if (!miniApp?.clientId || !miniApp.clientSecret) {
throw new AppException(ResponseCode.ChannelPlatformApiFailed, { platform: AccountType.Douyin, reasonCode: 'missing_miniapp_config' })
}
return miniApp
}
private get endpoints() {
return this.miniAppConfig.sandbox
? DOUYIN_MINIAPP_ENDPOINTS.sandbox
: DOUYIN_MINIAPP_ENDPOINTS.officialView on GitHub (pinned to d3aa8bea5b)
Solutions
- Inspect exception.cause.platformCode and platformMessage: Douyin-specific codes (e.g. invalid code, invalid appid) indicate config or expired login-code problems — fix appid/secret env values or have the client fetch a fresh js_code.
- If retryable is true (5xx or network-level error), retry with backoff; token-expiry codes should trigger token refresh, not blind retry.
- Use exception.context.endpoint to identify which mini-app API failed and validate that endpoint's required params.
- Verify outbound connectivity from the server to Douyin open-platform domains; reproduce with curl from the same host.
Example fix
// before: blind retry burns the single-use js_code
try {
session = await miniAppService.code2session(code)
} catch {
return this.retryWithBackoff(code)
}
// after: only retry when the exception is classified retryable
try {
session = await miniAppService.code2session(code)
} catch (e) {
if (e instanceof ChannelPlatformException && e.retryable) {
return this.retryWithBackoff(e)
}
throw e // e.g. invalid js_code / appid — needs new code or config fix
} Defensive patterns
Strategy: try-catch
Validate before calling
// validate js_code before exchange and config before boot
if (!code || code.length < 16) {
throw new Error('miniapp login code missing or malformed')
}
if (!config.douyinMiniAppAppId || !config.douyinMiniAppSecret) {
throw new Error('Douyin mini-app appid/secret not configured')
} Type guard
import { ChannelPlatformException } from '../channels/platforms/platforms.exception'
function isDouyinPlatformError(e: unknown): e is ChannelPlatformException {
return e instanceof ChannelPlatformException
&& e.platform === 'douyin'
&& (e.cause?.platformCode !== undefined || typeof e.cause?.httpStatus === 'number')
} Try / catch
try {
session = await douyinMiniAppService.code2session(code)
} catch (e) {
if (isDouyinPlatformError(e) && e.retryable) {
return retryWithBackoff(e)
}
throw e // invalid js_code/appid errors are not retryable
} Prevention
- Remember js_code is single-use and short-lived: never retry code2session with the same code; get a fresh one from the client.
- Keep mini-app appid/secret in validated config; fail at boot, not at first login.
- Cache access_token with expiry tracking and refresh ahead of calls instead of hitting token endpoints repeatedly.
- Verify outbound connectivity to Douyin open-platform domains in deploy health checks.
- Branch on cause.platformCode to distinguish config errors (appid/secret) from user-flow errors (expired code).
When it happens
Trigger: Any request through this mini-app client to Douyin open-platform endpoints (jscode2session code exchange, token endpoints, mini-app publishing APIs) that gets a non-2xx HTTP status, times out, fails DNS/connection, or returns 200 with a non-zero error_code such as invalid js_code, expired access_token, or appid/secret mismatch.
Common situations: Wrong Douyin mini-app appid/secret in env config making code2session calls fail; the user's login code already consumed or expired (js_code is single-use); access_token cache expired mid-call; Douyin platform 5xx incidents; server egress blocked so axios rejects without a response.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/c5835225364a3b7f.
Report an issue: GitHub.