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.official

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. 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.
  2. If retryable is true (5xx or network-level error), retry with backoff; token-expiry codes should trigger token refresh, not blind retry.
  3. Use exception.context.endpoint to identify which mini-app API failed and validate that endpoint's required params.
  4. 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

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.