babalae/better-genshin-impact · error · NotifierException

Error sending Telegram notification: {ex.Message}

Error message

Error sending Telegram notification: {ex.Message}

What it means

Final catch-all for any exception inside SendAsync that is not NotifierException, HttpRequestException, or TaskCanceledException (the `when (ex is not NotifierException)` filter). Covers InvalidOperationException, JsonException from ValidateApiResponse's caller path, ObjectDisposedException, ArgumentException, etc.

Source

Thrown at BetterGenshinImpact/Service/Notifier/TelegramNotifier.cs:138

            if (content.Screenshot != null)
            {
                await SendImageMessageAsync(content.Screenshot, content.Message.Length < 1024 ? content.Message : null);
                if (content.Message.Length < 1024) return;
            }

            await SendTextMessageAsync(content.Message);
        }
        catch (HttpRequestException ex)
        {
            throw new NotifierException("Network error sending Telegram notification: " + ex.Message);
        }
        catch (TaskCanceledException)
        {
            throw new NotifierException("Telegram API request timed out. Check your internet connection.");
        }
        catch (System.Exception ex) when (ex is not NotifierException)
        {
            throw new NotifierException("Error sending Telegram notification: " + ex.Message);
        }
    }

    private async Task SendImageMessageAsync(Image<Rgb24> image, string? caption)
    {
        var endpoint = $"{TelegramApiBaseUrl}{TelegramBotToken}/sendPhoto";
        using var memoryStream = new MemoryStream();
        await image.SaveAsPngAsync(memoryStream);
        memoryStream.Position = 0;

        var content = new MultipartFormDataContent
        {
            { new StreamContent(memoryStream), "photo", "image.png" },
            { new StringContent(TelegramChatId), "chat_id" }
        };
        if (!string.IsNullOrEmpty(caption)) content.Add(new StringContent(caption), "caption");

        await SendRequestAsync(endpoint, content, "image");

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Preserve ex as InnerException for stack-trace diagnosis.
  2. Add a dedicated JsonException catch with a clearer 'non-JSON Telegram response' message.
  3. Guard against use-after-Dispose of the notifier.
  4. Log the full exception type name in the message.

Example fix

// before
catch (System.Exception ex) when (ex is not NotifierException)
{
    throw new NotifierException("Error sending Telegram notification: " + ex.Message);
}

// after
catch (JsonException ex)
{
    throw new NotifierException("Telegram returned a non-JSON response: " + ex.Message, ex);
}
catch (System.Exception ex) when (ex is not NotifierException)
{
    throw new NotifierException($"Error sending Telegram notification ({ex.GetType().Name}): {ex.Message}", ex);
}
Defensive patterns

Strategy: try-catch

Try / catch

try { await telegramNotifier.SendAsync(data); }
catch (NotifierException ex) when (ex.Message.StartsWith("Error sending Telegram"))
{ /* unexpected — log full type + stack, do not silently retry */ }

Prevention

When it happens

Trigger: An unexpected exception type escapes the inner try — e.g. JsonException if SendRequestAsync's response is non-JSON and ValidateApiResponse's own try/catch is bypassed, or ObjectDisposedException if the notifier is used after Dispose.

Common situations: Telegram API returns HTML (proxy error page) breaking JSON parse; the notifier disposed but still referenced; an unforeseen framework exception.

Related errors


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