RayWangQvQ/BiliBiliToolPro · error · BiliIntegrationException

获取青龙token失败

Error message

获取青龙token失败

What it means

Thrown by SaveCookieToQinLongAsync when GetQingLongAuthTokenAsync returns null/empty, meaning no QingLong panel auth token could be obtained. The library needs this token to call QingLong's env API and cannot persist the Bilibili cookie without it — a BiliIntegrationException is thrown.

Solutions

  1. Verify QingLong ClientId and ClientSecret are configured (QingLong panel → 应用设置 → create an app with env read/write permission).
  2. Confirm the QingLong panel URL is reachable from the machine running the tool.
  3. Call the QingLong /open/auth/token endpoint manually with your clientId/clientSecret to verify credentials.
  4. Check QingLong panel version — older/newer versions may use different auth APIs.

Example fix

// before: no config check
var token = await GetQingLongAuthTokenAsync();
// after: validate config first
if (string.IsNullOrEmpty(qingLongOptions.Value.ClientId) || string.IsNullOrEmpty(qingLongOptions.Value.ClientSecret))
    throw new Exception("请先在青龙面板创建应用并配置 ClientId/ClientSecret");
var token = await GetQingLongAuthTokenAsync();
Defensive patterns

Strategy: validation

Validate before calling

// before calling SaveCookieToQinLongAsync
var opts = qingLongOptions.Value;
if (string.IsNullOrEmpty(opts.Url)) throw new Exception("未配置青龙面板地址");
if (string.IsNullOrEmpty(opts.ClientId) || string.IsNullOrEmpty(opts.ClientSecret))
    throw new Exception("未配置青龙 ClientId/ClientSecret,请在青龙面板创建应用");

Type guard

bool IsQingLongConfigured(QingLongOptions o) =>
    !string.IsNullOrWhiteSpace(o.Url) &&
    !string.IsNullOrWhiteSpace(o.ClientId) &&
    !string.IsNullOrWhiteSpace(o.ClientSecret);

Try / catch

try
{
    await loginDomainService.SaveCookieToQinLongAsync(ck);
}
catch (BiliIntegrationException ex) when (ex.Message.Contains("token"))
{
    logger.LogError("青龙鉴权失败,请检查 ClientId/ClientSecret:{msg}", ex.Message);
}

Prevention

When it happens

Trigger: GetQingLongAuthTokenAsync fails to produce a token — typically QingLong's ClientId/ClientSecret configuration is missing/empty/wrong, or the token endpoint is unreachable/returns no token.

Common situations: QingLong panel not deployed or URL misconfigured; ClientId/ClientSecret env vars not set in the QingLong panel; QingLong auth API changed between panel versions.

Related errors


AI-assisted analysis of RayWangQvQ/BiliBiliToolPro@c599b2c0da (2026-09-12). Data as JSON: /api/errors/b38ce11b7de18515. Report an issue: GitHub.

Appendix: source

Thrown at src/Ray.BiliBiliTool.DomainService/LoginDomainService.cs:246

        }

        logger.LogInformation("已存在该用户,更新cookie");
        lines[indexOfTargetCk] = $@"    ""{ckInfo.CookieStr}"",";
        await SaveJson(lines, fileInfo);
        logger.LogInformation("更新成功!");
    }

    public async Task<bool> SaveCookieToQinLongAsync(
        BiliCookie ckInfo,
        CancellationToken cancellationToken
    )
    {
        try
        {
            var token = await GetQingLongAuthTokenAsync();
            if (string.IsNullOrEmpty(token))
            {
                throw new BiliIntegrationException("获取青龙token失败");
            }

            var qlEnvList = await qingLongApi.GetEnvsAsync("Ray_BiliBiliCookies__", token);
            if (qlEnvList.Code != 200)
            {
                throw new BiliIntegrationException($"查询环境变量失败:{qlEnvList.ToJsonStr()}");
            }

            logger.LogDebug(qlEnvList.Data.ToJsonStr());
            logger.LogDebug(ckInfo.ToString());

            var list = qlEnvList
                .Data.Where(x => x.name.StartsWith("Ray_BiliBiliCookies__"))
                .ToList();
            var oldEnv = list.FirstOrDefault(x => x.value.Contains(ckInfo.UserId));

            if (oldEnv != null)
            {

View on GitHub (pinned to c599b2c0da)