{"record":{"id":"f5c6583a3561be58","repo":"babalae/better-genshin-impact","slug":"http-https","errorCode":null,"errorMessage":"请输入有效的 HTTP/HTTPS 图片地址。","messagePattern":"请输入有效的 HTTP/HTTPS 图片地址。","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/Service/BannerImageService.cs","lineNumber":69,"sourceCode":"        {\n            File.WriteAllText(tempPath, url, new UTF8Encoding(false));\n            lock (_fileCommitLock)\n            {\n                File.Move(tempPath, UrlConfigPath, true);\n            }\n        }\n        finally\n        {\n            TryDeleteFile(tempPath);\n        }\n    }\n\n    public async Task<bool> DownloadAndSaveAsync(string url, CancellationToken cancellationToken = default)\n    {\n        if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)\n            || (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps))\n        {\n            throw new ArgumentException(\"请输入有效的 HTTP/HTTPS 图片地址。\", nameof(url));\n        }\n\n        var operationId = Interlocked.Increment(ref _latestOperationId);\n        var directory = Path.GetDirectoryName(NetworkImagePath)\n                        ?? throw new InvalidOperationException(\"无法确定网络背景图片目录。\");\n        Directory.CreateDirectory(directory);\n        var tempPath = $\"{NetworkImagePath}.{Guid.NewGuid():N}.tmp\";\n\n        using var timeoutCancellationTokenSource = new CancellationTokenSource(DownloadTimeout);\n        using var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(\n            cancellationToken,\n            timeoutCancellationTokenSource.Token);\n        var linkedCancellationToken = linkedCancellationTokenSource.Token;\n\n        try\n        {\n            // 下载图片\n            using var response = await _httpClient.GetAsync(","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Service/BannerImageService.cs#L51-L87","documentation":"An ArgumentException thrown by BannerImageService.DownloadAndSaveAsync when the supplied url is not an absolute URI or its scheme is neither http nor https. Uri.TryCreate with UriKind.Absolute must succeed and the scheme is checked against the standard http/https schemes; anything else (ftp, file, relative path, malformed string) is rejected before any network call.","triggerScenarios":"Passing a relative URL, a file path, an ftp/data URI, or a malformed string (missing scheme/host) to DownloadAndSaveAsync. Also a url that is null or whitespace where TryCreate fails.","commonSituations":"User pastes a bare path or a CDN link missing 'https://'; a config/setting stored the URL without scheme; clipboard content with leading spaces or a wrapped link; an ftp:// or file:// link mistaken for an image URL.","solutions":["Provide a fully-qualified URL starting with http:// or https:// (e.g. https://example.com/bg.png).","Trim whitespace and validate the URL in the UI before calling DownloadAndSaveAsync.","If users may omit the scheme, prepend 'https://' client-side before validation.","Catch ArgumentException and show a field-level validation message to the user."],"exampleFix":"// before\nawait _banner.DownloadAndSaveAsync(userInput);\n// after\nvar url = userInput.Trim();\nif (!url.StartsWith(\"http://\", StringComparison.OrdinalIgnoreCase)\n    && !url.StartsWith(\"https://\", StringComparison.OrdinalIgnoreCase))\n{\n    url = \"https://\" + url;\n}\nif (!Uri.TryCreate(url, UriKind.Absolute, out _))\n{\n    Toast.Warning(\"请输入有效的 HTTP/HTTPS 图片地址。\");\n    return;\n}\nawait _banner.DownloadAndSaveAsync(url);","handlingStrategy":"validation","validationCode":"if (!Uri.TryCreate(url?.Trim(), UriKind.Absolute, out var uri)\n    || (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps))\n{\n    Toast.Warning(\"请输入有效的 HTTP/HTTPS 图片地址。\");\n    return;\n}","typeGuard":"static bool IsAbsoluteHttpUrl(string s) => Uri.TryCreate(s, UriKind.Absolute, out var u) && (u.Scheme == Uri.UriSchemeHttp || u.Scheme == Uri.UriSchemeHttps);","tryCatchPattern":"try { await _banner.DownloadAndSaveAsync(url, ct); }\ncatch (ArgumentException ex) { Toast.Warning(ex.Message); }","preventionTips":["Validate and trim the URL in the UI before calling.","Prepend 'https://' when the user omits the scheme.","Show a field-level validation message on ArgumentException."],"tags":["validation","url","download","argument"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}