{"record":{"id":"b38ce11b7de18515","repo":"RayWangQvQ/BiliBiliToolPro","slug":"token","errorCode":null,"errorMessage":"获取青龙token失败","messagePattern":"获取青龙token失败","errorType":"exception","errorClass":"BiliIntegrationException","httpStatus":null,"severity":"error","filePath":"src/Ray.BiliBiliTool.DomainService/LoginDomainService.cs","lineNumber":246,"sourceCode":"        }\n\n        logger.LogInformation(\"已存在该用户，更新cookie\");\n        lines[indexOfTargetCk] = $@\"    \"\"{ckInfo.CookieStr}\"\",\";\n        await SaveJson(lines, fileInfo);\n        logger.LogInformation(\"更新成功！\");\n    }\n\n    public async Task<bool> SaveCookieToQinLongAsync(\n        BiliCookie ckInfo,\n        CancellationToken cancellationToken\n    )\n    {\n        try\n        {\n            var token = await GetQingLongAuthTokenAsync();\n            if (string.IsNullOrEmpty(token))\n            {\n                throw new BiliIntegrationException(\"获取青龙token失败\");\n            }\n\n            var qlEnvList = await qingLongApi.GetEnvsAsync(\"Ray_BiliBiliCookies__\", token);\n            if (qlEnvList.Code != 200)\n            {\n                throw new BiliIntegrationException($\"查询环境变量失败：{qlEnvList.ToJsonStr()}\");\n            }\n\n            logger.LogDebug(qlEnvList.Data.ToJsonStr());\n            logger.LogDebug(ckInfo.ToString());\n\n            var list = qlEnvList\n                .Data.Where(x => x.name.StartsWith(\"Ray_BiliBiliCookies__\"))\n                .ToList();\n            var oldEnv = list.FirstOrDefault(x => x.value.Contains(ckInfo.UserId));\n\n            if (oldEnv != null)\n            {","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/RayWangQvQ/BiliBiliToolPro/blob/c599b2c0da964e16ea8c454397aa07bb16212628/src/Ray.BiliBiliTool.DomainService/LoginDomainService.cs#L228-L264","documentation":"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.","triggerScenarios":"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.","commonSituations":"QingLong panel not deployed or URL misconfigured; ClientId/ClientSecret env vars not set in the QingLong panel; QingLong auth API changed between panel versions.","solutions":["Verify QingLong ClientId and ClientSecret are configured (QingLong panel → 应用设置 → create an app with env read/write permission).","Confirm the QingLong panel URL is reachable from the machine running the tool.","Call the QingLong /open/auth/token endpoint manually with your clientId/clientSecret to verify credentials.","Check QingLong panel version — older/newer versions may use different auth APIs."],"exampleFix":"// before: no config check\nvar token = await GetQingLongAuthTokenAsync();\n// after: validate config first\nif (string.IsNullOrEmpty(qingLongOptions.Value.ClientId) || string.IsNullOrEmpty(qingLongOptions.Value.ClientSecret))\n    throw new Exception(\"请先在青龙面板创建应用并配置 ClientId/ClientSecret\");\nvar token = await GetQingLongAuthTokenAsync();","handlingStrategy":"validation","validationCode":"// before calling SaveCookieToQinLongAsync\nvar opts = qingLongOptions.Value;\nif (string.IsNullOrEmpty(opts.Url)) throw new Exception(\"未配置青龙面板地址\");\nif (string.IsNullOrEmpty(opts.ClientId) || string.IsNullOrEmpty(opts.ClientSecret))\n    throw new Exception(\"未配置青龙 ClientId/ClientSecret，请在青龙面板创建应用\");","typeGuard":"bool IsQingLongConfigured(QingLongOptions o) =>\n    !string.IsNullOrWhiteSpace(o.Url) &&\n    !string.IsNullOrWhiteSpace(o.ClientId) &&\n    !string.IsNullOrWhiteSpace(o.ClientSecret);","tryCatchPattern":"try\n{\n    await loginDomainService.SaveCookieToQinLongAsync(ck);\n}\ncatch (BiliIntegrationException ex) when (ex.Message.Contains(\"token\"))\n{\n    logger.LogError(\"青龙鉴权失败，请检查 ClientId/ClientSecret：{msg}\", ex.Message);\n}","preventionTips":["Create the QingLong application with env read/write permissions before enabling the sync.","Rotate ClientSecret and update config together.","Verify panel reachability with a simple HTTP call before running scheduled syncs."],"tags":["qinglong","auth-token","configuration","integration"],"backgroundTag":"missing-credentials","analyzedSha":"c599b2c0da964e16ea8c454397aa07bb16212628","analyzedAt":"2026-09-12T09:48:04.090Z","contentChangedAt":"2026-09-12T09:48:04.090Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}