From a794b6ed549cd8cf49eb66787da953dc28556ecc Mon Sep 17 00:00:00 2001 From: Rikitav Date: Mon, 4 Aug 2025 05:11:59 +0400 Subject: [PATCH] * Version incremented * Added ability to handle errors during filters validation inside Handlers * Moved Result class to root directory * Added FilterOrigin enum --- .../Telegrator.Hosting.Web.csproj | 2 +- Telegrator.Hosting/Telegrator.Hosting.csproj | 2 +- Telegrator/Aspects/IPostProcessor.cs.cs | 3 +- Telegrator/Aspects/IPreProcessor.cs | 3 +- Telegrator/Enums.cs | 28 +++++++ .../Handlers/Components/UpdateHandlerBase.cs | 23 ++++-- Telegrator/Handlers/Result.cs | 59 -------------- .../Descriptors/DescriptorAspectsSet.cs | 1 - .../Descriptors/DescriptorFiltersSet.cs | 12 ++- Telegrator/Polling/UpdateHandlersPool.cs | 3 +- Telegrator/Polling/UpdateRouter.cs | 17 +++- Telegrator/Result.cs | 80 +++++++++++++++++++ Telegrator/Telegrator.csproj | 2 +- 13 files changed, 156 insertions(+), 79 deletions(-) delete mode 100644 Telegrator/Handlers/Result.cs create mode 100644 Telegrator/Result.cs diff --git a/Telegrator.Hosting.Web/Telegrator.Hosting.Web.csproj b/Telegrator.Hosting.Web/Telegrator.Hosting.Web.csproj index aa94d56..211d0b5 100644 --- a/Telegrator.Hosting.Web/Telegrator.Hosting.Web.csproj +++ b/Telegrator.Hosting.Web/Telegrator.Hosting.Web.csproj @@ -15,7 +15,7 @@ True LICENSE README.md - 1.0.10 + 1.0.11 diff --git a/Telegrator.Hosting/Telegrator.Hosting.csproj b/Telegrator.Hosting/Telegrator.Hosting.csproj index ea5cac7..49af79d 100644 --- a/Telegrator.Hosting/Telegrator.Hosting.csproj +++ b/Telegrator.Hosting/Telegrator.Hosting.csproj @@ -16,7 +16,7 @@ True LICENSE README.md - 1.0.10 + 1.0.11 diff --git a/Telegrator/Aspects/IPostProcessor.cs.cs b/Telegrator/Aspects/IPostProcessor.cs.cs index d471c69..d478130 100644 --- a/Telegrator/Aspects/IPostProcessor.cs.cs +++ b/Telegrator/Aspects/IPostProcessor.cs.cs @@ -1,5 +1,4 @@ -using Telegrator.Handlers; -using Telegrator.Handlers.Components; +using Telegrator.Handlers.Components; namespace Telegrator.Aspects { diff --git a/Telegrator/Aspects/IPreProcessor.cs b/Telegrator/Aspects/IPreProcessor.cs index 2bf5cb4..789d590 100644 --- a/Telegrator/Aspects/IPreProcessor.cs +++ b/Telegrator/Aspects/IPreProcessor.cs @@ -1,5 +1,4 @@ -using Telegrator.Handlers; -using Telegrator.Handlers.Components; +using Telegrator.Handlers.Components; namespace Telegrator.Aspects { diff --git a/Telegrator/Enums.cs b/Telegrator/Enums.cs index aa0c4a0..6c43850 100644 --- a/Telegrator/Enums.cs +++ b/Telegrator/Enums.cs @@ -70,6 +70,33 @@ Sender } + /// + /// Messages from where this filter was originated + /// + public enum FilterOrigin + { + /// + /// None, empty filter + /// + None, + + /// + /// From update validator filter + /// + Validator, + + /// + /// From state machine filter + /// + StateKeeper, + + /// + /// From regular + /// + Regualr + } + + /* /// /// Levels of debug writing /// @@ -101,4 +128,5 @@ /// HandlersPool = 0x8 } + */ } diff --git a/Telegrator/Handlers/Components/UpdateHandlerBase.cs b/Telegrator/Handlers/Components/UpdateHandlerBase.cs index 5eb4107..22fc0b1 100644 --- a/Telegrator/Handlers/Components/UpdateHandlerBase.cs +++ b/Telegrator/Handlers/Components/UpdateHandlerBase.cs @@ -1,10 +1,8 @@ -using System.ComponentModel; -using System.Threading; -using Telegram.Bot.Polling; +using Telegram.Bot.Polling; +using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegrator.MadiatorCore; +using Telegrator.Filters.Components; using Telegrator.MadiatorCore.Descriptors; -using Telegrator.Polling; namespace Telegrator.Handlers.Components { @@ -102,5 +100,20 @@ namespace Telegrator.Handlers.Components /// The cancellation token. /// A representing the asynchronous operation. protected abstract Task ExecuteInternal(IHandlerContainer container, CancellationToken cancellationToken); + + /// + /// Handles failed filters during handler describing. + /// Use to control how router should treat this fail. + /// to silently continue decribing. + /// to stop\break decribing sequence. + /// + /// + /// + /// + /// + public virtual Task FiltersFallback(FilterExecutionContext context, IFilter failedFilter, FilterOrigin origin) + { + return Task.FromResult(Result.Ok()); + } } } diff --git a/Telegrator/Handlers/Result.cs b/Telegrator/Handlers/Result.cs deleted file mode 100644 index a72660a..0000000 --- a/Telegrator/Handlers/Result.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace Telegrator.Handlers -{ - /// - /// Represents handler results, allowing to communicate with router and control aspect execution - /// - public sealed class Result - { - /// - /// Is result positive - /// - public bool Positive { get; } - - /// - /// Should router search for next matching handler - /// - public bool RouteNext { get; } - - /// - /// Exact type that router should search - /// - public Type? NextType { get; } - - internal Result(bool positive, bool routeNext, Type? nextType) - { - Positive = positive; - RouteNext = routeNext; - NextType = nextType; - } - - /// - /// "OK" result - /// - /// - public static Result Ok() - => new Result(true, false, null); - - /// - /// "Somethong went wrong" result - /// - /// - public static Result Fault() - => new Result(false, false, null); - - /// - /// "Search next handler" result - /// - /// - public static Result Next() - => new Result(true, true, null); - - /// - /// "Search next handler of type" result - /// - /// - /// - public static Result Next() - => new Result(true, true, typeof(T)); - } -} diff --git a/Telegrator/MadiatorCore/Descriptors/DescriptorAspectsSet.cs b/Telegrator/MadiatorCore/Descriptors/DescriptorAspectsSet.cs index fe62b8b..4a20260 100644 --- a/Telegrator/MadiatorCore/Descriptors/DescriptorAspectsSet.cs +++ b/Telegrator/MadiatorCore/Descriptors/DescriptorAspectsSet.cs @@ -1,5 +1,4 @@ using Telegrator.Aspects; -using Telegrator.Handlers; using Telegrator.Handlers.Components; namespace Telegrator.MadiatorCore.Descriptors diff --git a/Telegrator/MadiatorCore/Descriptors/DescriptorFiltersSet.cs b/Telegrator/MadiatorCore/Descriptors/DescriptorFiltersSet.cs index 66ce1a6..a38b48d 100644 --- a/Telegrator/MadiatorCore/Descriptors/DescriptorFiltersSet.cs +++ b/Telegrator/MadiatorCore/Descriptors/DescriptorFiltersSet.cs @@ -41,14 +41,18 @@ namespace Telegrator.MadiatorCore.Descriptors /// Validates the filter context using all filters in the set. /// /// The filter execution context. + /// + /// /// True if all filters pass; otherwise, false. - public bool Validate(FilterExecutionContext filterContext) + public bool Validate(FilterExecutionContext filterContext, out IFilter failedFilter, out FilterOrigin origin) { if (UpdateValidator != null) { if (!UpdateValidator.CanPass(filterContext)) { Alligator.LogDebug("(E) UpdateValidator filter of {0} for Update ({1}) didnt pass!", filterContext.Data["handler_name"], filterContext.Update.Id); + failedFilter = UpdateValidator; + origin = FilterOrigin.Validator; return false; } @@ -61,6 +65,8 @@ namespace Telegrator.MadiatorCore.Descriptors if (!StateKeeperValidator.CanPass(filterContext)) { Alligator.LogDebug("(E) StateKeeperValidator filter of {0} for Update ({1}) didnt pass!", filterContext.Data["handler_name"], filterContext.Update.Id); + failedFilter = StateKeeperValidator; + origin = FilterOrigin.StateKeeper; return false; } @@ -77,6 +83,8 @@ namespace Telegrator.MadiatorCore.Descriptors if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter) Alligator.LogDebug("(E) {0} filter of {1} for Update ({2}) didnt pass!", filter.GetType().Name, filterContext.Data["handler_name"], filterContext.Update.Id); + failedFilter = filter; + origin = FilterOrigin.Regualr; return false; } @@ -85,6 +93,8 @@ namespace Telegrator.MadiatorCore.Descriptors } } + failedFilter = null!; + origin = FilterOrigin.None; return true; } } diff --git a/Telegrator/Polling/UpdateHandlersPool.cs b/Telegrator/Polling/UpdateHandlersPool.cs index 83ca2f3..22023e4 100644 --- a/Telegrator/Polling/UpdateHandlersPool.cs +++ b/Telegrator/Polling/UpdateHandlersPool.cs @@ -1,5 +1,4 @@ -using Telegrator.Handlers; -using Telegrator.Logging; +using Telegrator.Logging; using Telegrator.MadiatorCore; using Telegrator.MadiatorCore.Descriptors; diff --git a/Telegrator/Polling/UpdateRouter.cs b/Telegrator/Polling/UpdateRouter.cs index 731f267..3e55b21 100644 --- a/Telegrator/Polling/UpdateRouter.cs +++ b/Telegrator/Polling/UpdateRouter.cs @@ -215,11 +215,18 @@ namespace Telegrator.Polling { "handler_name", descriptor.ToString() } }; - FilterExecutionContext filterContext = new FilterExecutionContext(_botInfo, update, update, data, []); - if (descriptor.Filters != null && !descriptor.Filters.Validate(filterContext)) - return null; - UpdateHandlerBase handlerInstance = provider.GetHandlerInstance(descriptor, cancellationToken); + + FilterExecutionContext filterContext = new FilterExecutionContext(_botInfo, update, update, data, []); + if (descriptor.Filters != null && !descriptor.Filters.Validate(filterContext, out IFilter failedFilter, out FilterOrigin origin)) + { + Result fallbackResult = handlerInstance.FiltersFallback(filterContext, failedFilter, origin).Result; + if (!fallbackResult.Positive) + throw new BreakDescribingException(); + + return null; + } + return new DescribedHandlerInfo(descriptor, this, AwaitingProvider, client, handlerInstance, filterContext, descriptor.DisplayString); } @@ -266,5 +273,7 @@ namespace Telegrator.Polling } } } + + private class BreakDescribingException : Exception { } } } diff --git a/Telegrator/Result.cs b/Telegrator/Result.cs new file mode 100644 index 0000000..4d025b1 --- /dev/null +++ b/Telegrator/Result.cs @@ -0,0 +1,80 @@ +using Telegram.Bot.Types; +using Telegrator.Aspects; +using Telegrator.Handlers.Components; +using Telegrator.Filters.Components; +using Telegrator.MadiatorCore; + +namespace Telegrator +{ + /// + /// Represents handler results, allowing to communicate with router and control aspect execution + /// + public sealed class Result + { + /// + /// Is result positive + /// + public bool Positive { get; } + + /// + /// Should router search for next matching handler + /// + public bool RouteNext { get; } + + /// + /// Exact type that router should search + /// + public Type? NextType { get; } + + internal Result(bool positive, bool routeNext, Type? nextType) + { + Positive = positive; + RouteNext = routeNext; + NextType = nextType; + } + + /// + /// Represents 'success' + /// + /// Inside - let handler's main block be executed + /// Inside - let router continue describing + /// Inside - tells that he can stop describing, as needed handler was found + /// + /// + /// + public static Result Ok() + => new Result(true, false, null); + + /// + /// Represents 'fault' or 'error'. Use cases: + /// + /// Inside - interupts execution of handler, main block and wont be executed + /// Inside - interupts router's describing sequence + /// + /// + /// + public static Result Fault() + => new Result(false, false, null); + + /// + /// Represents 'continue'. Use cases: + /// + /// Inside - Tells to continue describing handlers + /// + /// + /// + public static Result Next() + => new Result(true, true, null); + + /// + /// Represents 'chain'. Use cases: + /// + /// Inside - Tells to continue describing handlers and execute only handlers of exact type + /// + /// + /// + /// + public static Result Next() + => new Result(true, true, typeof(T)); + } +} diff --git a/Telegrator/Telegrator.csproj b/Telegrator/Telegrator.csproj index 9b632ee..2ee8b14 100644 --- a/Telegrator/Telegrator.csproj +++ b/Telegrator/Telegrator.csproj @@ -17,7 +17,7 @@ True True LICENSE - 1.0.10 + 1.0.11