yikart/AiToEarn · error · BilibiliPlatformException
15070
15070
Error message
{{platform}} platform API request failed What it means
BilibiliService builds its Axios instance in createPlatformHttpClient with response interceptors that normalize every failure into a BilibiliPlatformException (a ChannelPlatformException) whose user-facing template is '{{platform}} platform API request failed' (code 15070). fromAxiosError fires for network-level failures (timeout, DNS, connection refused) and HTTP error statuses on calls to Bilibili open APIs; fromPlatformResponse fires when Bilibili returns HTTP 200 but a body code other than 0. The exception carries httpStatus, platformCode, endpoint context, a retryable flag, and a category so callers can classify it.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/bilibili/bilibili.service.ts:50
private readonly mediaService: MediaService,
) {
this.platformHttp = this.createPlatformHttpClient()
}
private readonly authPageUrl = 'https://account.bilibili.com/pc/account-pc/auth/oauth'
private readonly openBaseUrl = 'https://member.bilibili.com'
private createPlatformHttpClient(): AxiosInstance {
const http = axios.create()
http.interceptors.response.use(
(response) => {
if (BilibiliPlatformException.hasPlatformError(response)) {
throw BilibiliPlatformException.fromPlatformResponse(response)
}
return response
},
(error: AxiosError<BilibiliPlatformResponseBody>) => {
throw BilibiliPlatformException.fromAxiosError(error)
},
)
return http
}
generateAuthUrl(state: string): string {
const params = new URLSearchParams({
client_id: this.cfg.clientId,
gourl: this.cfg.redirectUri,
state,
})
return `${this.authPageUrl}?${params.toString()}`
}
async exchangeCode(code: string): Promise<{
accessToken: string
refreshToken: stringView on GitHub (pinned to d3aa8bea5b)
Solutions
- Read exception.cause.httpStatus and cause.platformCode: 401/-101 style codes mean reconnect the Bilibili account (refresh tokens via the channel service) rather than retrying.
- If retryable is true (5xx per isHttpStatusRetryable, or no response = network error), retry the request with backoff.
- Check the endpoint in exception.context to identify which Bilibili API failed and verify app credentials/env config for that endpoint.
- Confirm outbound network access (proxy, DNS, firewall) from the server to the Bilibili open API; reproduce with curl from the same container.
Example fix
// before: treating every platform failure the same
try {
await bilibiliService.publish(account, payload)
} catch (e) {
this.logger.error('publish failed')
}
// after: branch on the classified ChannelPlatformException
try {
await bilibiliService.publish(account, payload)
} catch (e) {
if (e instanceof ChannelPlatformException) {
if (e.retryable) return this.retryWithBackoff(e)
if (e.cause?.httpStatus === 401) return this.markAccountReauthRequired(account)
}
throw e
} Defensive patterns
Strategy: try-catch
Validate before calling
// before calling: fail fast on missing credentials and check account token presence
if (!config.bilibiliAppKey || !config.bilibiliAppSecret) {
throw new Error('BILIBILI app credentials are not configured')
}
if (!account.accessToken) {
throw new Error(`Bilibili account ${account.id} has no access token; reconnect required`)
} Type guard
import { ChannelPlatformException } from '../channels/platforms/platforms.exception'
function isBilibiliPlatformError(e: unknown): e is ChannelPlatformException {
return e instanceof ChannelPlatformException
&& e.platform === 'bilibili'
&& (e.cause?.httpStatus !== undefined || e.cause?.platformCode !== undefined)
} Try / catch
try {
return await bilibiliService.publish(account, payload)
} catch (e) {
if (isBilibiliPlatformError(e)) {
if (e.retryable) return retryWithBackoff(e)
if (e.cause.httpStatus === 401) return markAccountNeedsReauth(account.id)
}
throw e
} Prevention
- Always branch on ChannelPlatformException's retryable flag and cause.httpStatus instead of catching bare Error.
- Refresh/validate Bilibili tokens before long publish jobs; proactively reconnect accounts with near-expiry tokens.
- Add alerting on PlatformErrorCategory.PlatformUnavailable so Bilibili 5xx incidents trigger backoff, not error storms.
- Smoke-test outbound connectivity to the Bilibili open API in deployment health checks.
- Regenerate one-time request payloads before each retry instead of reusing them.
When it happens
Trigger: Any axios request through this client whose promise rejects (network error, timeout, 4xx/5xx status), or where Bilibili responds with a non-zero body `code` (e.g. -101 invalid access_token, -352 risk control); typical call sites are OAuth token exchange, auth-url flows, and content publishing via the interceptor-wrapped http instance.
Common situations: Expired or revoked Bilibili access tokens bound to the connected account; Bilibili API downtime or 5xx during publishes; hitting Bilibili rate limits/risk control (-352, -412); misconfigured Bilibili app credentials causing 4xx on token endpoints; container DNS/proxy issues blocking outbound calls.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/4f80c87a55c0d5e1.
Report an issue: GitHub.