fix!: prevent exceptions from being muted

happens by not awaiting tasks
This commit is contained in:
ZavaruKitsu 2022-10-08 20:00:21 +03:00
parent f41fdf90ed
commit f9d25dfb83
9 changed files with 61 additions and 55 deletions

View File

@ -33,4 +33,4 @@ public class StartForm : FormBase
user.LastMessage = string.IsNullOrWhiteSpace(message.MessageText) ? "<unknown>" : message.MessageText; user.LastMessage = string.IsNullOrWhiteSpace(message.MessageText) ? "<unknown>" : message.MessageText;
await _dbContext.SaveChangesAsync(); await _dbContext.SaveChangesAsync();
} }
} }

View File

@ -7,7 +7,7 @@ namespace TelegramBotBase.Base;
public static class Async public static class Async
{ {
public delegate Task AsyncEventHandler<TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs; public delegate Task AsyncEventHandler<in TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs;
public static IEnumerable<AsyncEventHandler<TEventArgs>> GetHandlers<TEventArgs>( public static IEnumerable<AsyncEventHandler<TEventArgs>> GetHandlers<TEventArgs>(
this AsyncEventHandler<TEventArgs> handler) this AsyncEventHandler<TEventArgs> handler)
@ -24,4 +24,4 @@ public static class Async
handler.GetHandlers() handler.GetHandlers()
.Select(handleAsync => handleAsync(sender, e))); .Select(handleAsync => handleAsync(sender, e)));
} }
} }

View File

@ -41,7 +41,6 @@ public class MessageClient
ApiKey = apiKey; ApiKey = apiKey;
TelegramClient = new TelegramBotClient(apiKey, proxy); TelegramClient = new TelegramBotClient(apiKey, proxy);
Prepare(); Prepare();
} }
@ -124,11 +123,9 @@ public class MessageClient
} }
public Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) public async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
{ {
OnMessageLoop(new UpdateResult(update, null)); await OnMessageLoop(new UpdateResult(update, null));
return Task.CompletedTask;
} }
public Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, public Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception,
@ -161,6 +158,7 @@ public class MessageClient
/// This will set your bot commands to the given list. /// This will set your bot commands to the given list.
/// </summary> /// </summary>
/// <param name="botcommands"></param> /// <param name="botcommands"></param>
/// <param name="languageCode"></param>
/// <returns></returns> /// <returns></returns>
public async Task SetBotCommands(List<BotCommand> botcommands, BotCommandScope scope = null, public async Task SetBotCommands(List<BotCommand> botcommands, BotCommandScope scope = null,
string languageCode = null) string languageCode = null)
@ -186,10 +184,10 @@ public class MessageClient
remove => Events.RemoveHandler(EvOnMessageLoop, value); remove => Events.RemoveHandler(EvOnMessageLoop, value);
} }
public void OnMessageLoop(UpdateResult update) public async Task OnMessageLoop(UpdateResult update)
{ {
(Events[EvOnMessageLoop] as Async.AsyncEventHandler<UpdateResult>)?.Invoke(this, update); await (Events[EvOnMessageLoop] as Async.AsyncEventHandler<UpdateResult>)?.Invoke(this, update);
} }
#endregion #endregion
} }

View File

@ -108,32 +108,40 @@ public class BotBase
private async Task Client_MessageLoop(object sender, UpdateResult e) private async Task Client_MessageLoop(object sender, UpdateResult e)
{ {
var ds = Sessions.GetSession(e.DeviceId); try
if (ds == null)
{ {
ds = Sessions.StartSession(e.DeviceId).GetAwaiter().GetResult(); var ds = Sessions.GetSession(e.DeviceId);
e.Device = ds; if (ds == null)
ds.LastMessage = e.RawData.Message; {
ds = await Sessions.StartSession(e.DeviceId);
e.Device = ds;
ds.LastMessage = e.RawData.Message;
OnSessionBegins(new SessionBeginEventArgs(e.DeviceId, ds)); OnSessionBegins(new SessionBeginEventArgs(e.DeviceId, ds));
}
var mr = new MessageResult(e.RawData);
var i = 0;
//Should formulars get navigated (allow maximum of 10, to dont get loops)
do
{
i++;
//Reset navigation
ds.FormSwitched = false;
await MessageLoopFactory.MessageLoop(this, ds, e, mr);
mr.IsFirstHandler = false;
} while (ds.FormSwitched && i < GetSetting(ESettings.NavigationMaximum, 10));
} }
catch (Exception ex)
var mr = new MessageResult(e.RawData);
var i = 0;
//Should formulars get navigated (allow maximum of 10, to dont get loops)
do
{ {
i++; var ds = Sessions.GetSession(e.DeviceId);
OnException(new SystemExceptionEventArgs(e.Message.Text, e.DeviceId, ds, ex));
//Reset navigation }
ds.FormSwitched = false;
await MessageLoopFactory.MessageLoop(this, ds, e, mr);
mr.IsFirstHandler = false;
} while (ds.FormSwitched && i < GetSetting(ESettings.NavigationMaximum, 10));
} }
@ -390,7 +398,7 @@ public class BotBase
} }
/// <summary> /// <summary>
/// Will be called if no form handeled this call /// Will be called if no form handled this call
/// </summary> /// </summary>
public event EventHandler<UnhandledCallEventArgs> UnhandledCall public event EventHandler<UnhandledCallEventArgs> UnhandledCall
{ {

View File

@ -41,24 +41,24 @@ public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage,
public BotBase Build() public BotBase Build()
{ {
var bb = new BotBase var bot = new BotBase
{ {
ApiKey = _apiKey, ApiKey = _apiKey,
StartFormFactory = _factory, StartFormFactory = _factory,
Client = _client Client = _client
}; };
bb.Sessions.Client = bb.Client; bot.Sessions.Client = bot.Client;
bb.BotCommandScopes = BotCommandScopes; bot.BotCommandScopes = BotCommandScopes;
bb.StateMachine = _statemachine; bot.StateMachine = _statemachine;
bb.MessageLoopFactory = _messageLoopFactory; bot.MessageLoopFactory = _messageLoopFactory;
bb.MessageLoopFactory.UnhandledCall += bb.MessageLoopFactory_UnhandledCall; bot.MessageLoopFactory.UnhandledCall += bot.MessageLoopFactory_UnhandledCall;
return bb; return bot;
} }
public static IAPIKeySelectionStage Create() public static IAPIKeySelectionStage Create()
@ -75,10 +75,10 @@ public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage,
} }
public IBuildingStage QuickStart(string apiKey, Type StartForm) public IBuildingStage QuickStart(string apiKey, Type startForm)
{ {
_apiKey = apiKey; _apiKey = apiKey;
_factory = new DefaultStartFormFactory(StartForm); _factory = new DefaultStartFormFactory(startForm);
DefaultMessageLoop(); DefaultMessageLoop();
@ -113,10 +113,10 @@ public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage,
return this; return this;
} }
public IBuildingStage QuickStart(string apiKey, IStartFormFactory StartFormFactory) public IBuildingStage QuickStart(string apiKey, IStartFormFactory startFormFactory)
{ {
_apiKey = apiKey; _apiKey = apiKey;
_factory = StartFormFactory; _factory = startFormFactory;
DefaultMessageLoop(); DefaultMessageLoop();
@ -218,7 +218,7 @@ public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage,
TelegramClient = TelegramClient =
{ {
Timeout = new TimeSpan(0, 1, 0) Timeout = new TimeSpan(0, 1, 0)
} },
}; };
return this; return this;
} }
@ -369,4 +369,4 @@ public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage,
} }
#endregion #endregion
} }

View File

@ -219,7 +219,7 @@ public class AutoCleanForm : FormBase
var retryAfterSeconds = ex.InnerExceptions var retryAfterSeconds = ex.InnerExceptions
.Where(e => e is ApiRequestException apiEx && apiEx.ErrorCode == 429) .Where(e => e is ApiRequestException apiEx && apiEx.ErrorCode == 429)
.Max(e => ((ApiRequestException)e).Parameters.RetryAfter) ?? 0; .Max(e => ((ApiRequestException)e).Parameters.RetryAfter) ?? 0;
retryAfterTask = Task.Delay(retryAfterSeconds * 1000); retryAfterTask = Task.Delay(retryAfterSeconds * 1000, cts.Token);
} }
//deletedMessages.AsParallel().ForAll(i => Device.OnMessageDeleted(new MessageDeletedEventArgs(i))); //deletedMessages.AsParallel().ForAll(i => Device.OnMessageDeleted(new MessageDeletedEventArgs(i)));
@ -236,4 +236,4 @@ public class AutoCleanForm : FormBase
OldMessages.Clear(); OldMessages.Clear();
} }
} }

View File

@ -107,7 +107,7 @@ public class FormBaseMessageLoop : IMessageLoopFactory
} }
/// <summary> /// <summary>
/// Will be called if no form handeled this call /// Will be called if no form handled this call
/// </summary> /// </summary>
public event EventHandler<UnhandledCallEventArgs> UnhandledCall public event EventHandler<UnhandledCallEventArgs> UnhandledCall
{ {
@ -119,4 +119,4 @@ public class FormBaseMessageLoop : IMessageLoopFactory
{ {
(_events[EvUnhandledCall] as EventHandler<UnhandledCallEventArgs>)?.Invoke(this, e); (_events[EvUnhandledCall] as EventHandler<UnhandledCallEventArgs>)?.Invoke(this, e);
} }
} }

View File

@ -100,7 +100,7 @@ public class FullMessageLoop : IMessageLoopFactory
} }
/// <summary> /// <summary>
/// Will be called if no form handeled this call /// Will be called if no form handled this call
/// </summary> /// </summary>
public event EventHandler<UnhandledCallEventArgs> UnhandledCall public event EventHandler<UnhandledCallEventArgs> UnhandledCall
{ {
@ -112,4 +112,4 @@ public class FullMessageLoop : IMessageLoopFactory
{ {
(_events[EvUnhandledCall] as EventHandler<UnhandledCallEventArgs>)?.Invoke(this, e); (_events[EvUnhandledCall] as EventHandler<UnhandledCallEventArgs>)?.Invoke(this, e);
} }
} }

View File

@ -31,7 +31,7 @@ public class MinimalMessageLoop : IMessageLoopFactory
} }
/// <summary> /// <summary>
/// Will be called if no form handeled this call /// Will be called if no form handled this call
/// </summary> /// </summary>
public event EventHandler<UnhandledCallEventArgs> UnhandledCall public event EventHandler<UnhandledCallEventArgs> UnhandledCall
{ {
@ -43,4 +43,4 @@ public class MinimalMessageLoop : IMessageLoopFactory
{ {
(_events[EvUnhandledCall] as EventHandler<UnhandledCallEventArgs>)?.Invoke(this, e); (_events[EvUnhandledCall] as EventHandler<UnhandledCallEventArgs>)?.Invoke(this, e);
} }
} }