diff --git a/src/Max.BotClient/Max.BotClient.Polling.cs b/src/Max.BotClient/Max.BotClient.Polling.cs index 3552cfb..b8b508d 100644 --- a/src/Max.BotClient/Max.BotClient.Polling.cs +++ b/src/Max.BotClient/Max.BotClient.Polling.cs @@ -42,19 +42,19 @@ public static partial class BotClientApiMethods /// Обработчик ошибок (необязательно). /// Опции polling. /// Токен отмены. - public static void StartReceiving( + public static Task StartReceiving( this IBotClient botClient, Func updateHandler, Func? errorHandler = null, ReceiverOptions? options = null, CancellationToken cancellationToken = default - ) => Task.Run(() => + ) => Task.Run(() => botClient.ReceiveAsync( - updateHandler, - errorHandler, - options, + updateHandler, + errorHandler, + options, cancellationToken - ), + ), cancellationToken ); @@ -92,14 +92,21 @@ public static async Task ReceiveAsync( ); marker = newMarker; } - catch (OperationCanceledException) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { return; } catch (Exception ex) { - if (errorHandler != null) - await errorHandler(botClient, ex, cancellationToken); + try + { + if (errorHandler != null) + await errorHandler(botClient, ex, cancellationToken); + } + catch + { + // Не позволяем errorHandler убить polling loop + } } } @@ -120,14 +127,31 @@ public static async Task ReceiveAsync( updates = result.Item1; marker = result.Item2 ?? marker; } - catch (OperationCanceledException) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { break; } catch (Exception ex) { - if (errorHandler != null) - await errorHandler(botClient, ex, cancellationToken); + try + { + if (errorHandler != null) + await errorHandler(botClient, ex, cancellationToken); + } + catch + { + // Не позволяем errorHandler убить polling loop + } + + // Backoff перед повторной попыткой, чтобы не забивать API при длительном сбое + try + { + await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); + } + catch (OperationCanceledException) + { + break; + } continue; } @@ -138,14 +162,21 @@ public static async Task ReceiveAsync( { await updateHandler(botClient, update, cancellationToken); } - catch (OperationCanceledException) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { return; } catch (Exception ex) { - if (errorHandler != null) - await errorHandler(botClient, ex, cancellationToken); + try + { + if (errorHandler != null) + await errorHandler(botClient, ex, cancellationToken); + } + catch + { + // Не позволяем errorHandler убить polling loop + } } } }