babalae/better-genshin-impact · error · NotifierException

ServerChan调用失败,状态码: {response.StatusCode}

Error message

ServerChan调用失败,状态码: {response.StatusCode}

What it means

Thrown when the POST to the ServerChan API URL (sctapi.ftqq.com/{key}.send or {num}.push.ft07.com/send/{key}.send) returns a non-success HTTP status. The notifier only checks response.IsSuccessStatusCode and discards the body.

Source

Thrown at BetterGenshinImpact/Service/Notifier/ServerChanNotifier.cs:58

            // 生成通知标题和内容
            string title = $"BetterGI·更好的原神";
            string desp = GenerateDescription(content);

            // 准备表单数据
            var postData = $"title={Uri.EscapeDataString(title)}&desp={Uri.EscapeDataString(desp)}";

            // 创建请求
            var request = new HttpRequestMessage(HttpMethod.Post, apiUrl);
            request.Content = new StringContent(postData, Encoding.UTF8, "application/x-www-form-urlencoded");

            // 发送请求
            var response = await _httpClient.SendAsync(request);

            // 检查响应状态
            if (!response.IsSuccessStatusCode)
            {
                throw new NotifierException($"ServerChan调用失败,状态码: {response.StatusCode}");
            }
        }
        catch (NotifierException)
        {
            throw;
        }
        catch (System.Exception ex)
        {
            throw new NotifierException($"Error sending ServerChan message: {ex.Message}");
        }
    }

    /// <summary>
    /// 根据sendKey格式获取正确的API URL
    /// </summary>
    private string GetServerChanApiUrl(string key)
    {
        // 判断sendkey是否以"sctp"开头并提取数字部分

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Read and include the response body in the exception (ServerChan returns JSON with code/message).
  2. Verify the SendKey is current and has no whitespace.
  3. For 429, throttle notifications (ServerChan free tier allows limited messages per minute).
  4. For sctp keys, confirm the numeric prefix matches the ft07 account.

Example fix

// before
var response = await _httpClient.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
    throw new NotifierException($"ServerChan调用失败,状态码: {response.StatusCode}");
}

// after
var response = await _httpClient.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
    throw new NotifierException($"ServerChan调用失败,状态码: {response.StatusCode}, 响应: {body}");
}
Defensive patterns

Strategy: retry

Validate before calling

if (string.IsNullOrWhiteSpace(sendKey))
    throw new InvalidOperationException("SendKey missing.");
string apiUrl = GetServerChanApiUrl(sendKey);
if (!Uri.TryCreate(apiUrl, UriKind.Absolute, out _))
    throw new InvalidOperationException("Built ServerChan URL is invalid.");

Try / catch

for (int attempt = 0; ; attempt++)
try { await serverChanNotifier.SendAsync(data); break; }
catch (NotifierException ex) when (ex.Message.Contains("调用失败") && attempt < 2)
{ await Task.Delay(TimeSpan.FromSeconds(5 * (attempt + 1))); }

Prevention

When it happens

Trigger: HTTP 400/401 (bad/expired key), 404 (wrong key path for sctp format), 429 (frequency limit — ServerChan limits ~5 msgs/min on free tier), 5xx (service down).

Common situations: SendKey revoked or pasted with trailing whitespace; free-tier rate limit exceeded; ft07 endpoint number wrong; service-side maintenance.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/3d4cb7fa173d4b7f. Report an issue: GitHub.