babalae/better-genshin-impact · error · NotifierException

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

Error message

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

What it means

Thrown when the POST to https://api.chuckfang.com/{nickname}[/title] returns a non-success HTTP status. The notifier does not inspect the body, only response.IsSuccessStatusCode, so any 4xx/5xx becomes this generic message including the StatusCode enum value.

Source

Thrown at BetterGenshinImpact/Service/Notifier/MeowNotifier.cs:46

        _nickname = nickname;
        _title = title;
    }

    public async Task SendAsync(BaseNotificationData content)
    {
        if (string.IsNullOrWhiteSpace(_nickname))
        {
            throw new NotifierException("MeoW 昵称为空");
        }

        try
        {
            var url = BuildUrl();
            using var response = await _httpClient.PostAsync(url, BuildContent(content));

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

    private string BuildUrl()
    {
        var url = $"https://api.chuckfang.com/{Uri.EscapeDataString(_nickname)}";
        if (!string.IsNullOrEmpty(_title))
        {
            url += $"/{Uri.EscapeDataString(_title)}";

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Read the response body and include it in the exception for diagnosis (the current code discards it).
  2. Verify the nickname exactly matches a registered MeoW account.
  3. For 429 responses, add backoff/retry before surfacing the error to the user.
  4. Check https://api.chuckfang.com status if 5xx persists.

Example fix

// before
using var response = await _httpClient.PostAsync(url, BuildContent(content));
if (!response.IsSuccessStatusCode)
{
    throw new NotifierException($"MeoW 调用失败,状态码: {response.StatusCode}");
}

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

Strategy: retry

Validate before calling

var url = $"https://api.chuckfang.com/{Uri.EscapeDataString(nickname)}";
if (!Uri.TryCreate(url, UriKind.Absolute, out _))
    throw new InvalidOperationException("Built MeoW URL is not valid.");

Try / catch

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

Prevention

When it happens

Trigger: _httpClient.PostAsync(url, BuildContent(content)) completes but response.IsSuccessStatusCode is false; common codes: 404 (unknown nickname/title), 429 (rate limit), 5xx (service down), 400 (malformed path).

Common situations: Nickname typo so the path 404s; chuckfang.com service outage; rapid repeated notifications triggering rate limiting; special characters in title that escape oddly.

Related errors


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