* Version incremented
* Added ability to handle errors during filters validation inside Handlers * Moved Result class to root directory * Added FilterOrigin enum
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
<Version>1.0.10</Version>
|
<Version>1.0.11</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
<Version>1.0.10</Version>
|
<Version>1.0.11</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Telegrator.Handlers;
|
using Telegrator.Handlers.Components;
|
||||||
using Telegrator.Handlers.Components;
|
|
||||||
|
|
||||||
namespace Telegrator.Aspects
|
namespace Telegrator.Aspects
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Telegrator.Handlers;
|
using Telegrator.Handlers.Components;
|
||||||
using Telegrator.Handlers.Components;
|
|
||||||
|
|
||||||
namespace Telegrator.Aspects
|
namespace Telegrator.Aspects
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -70,6 +70,33 @@
|
|||||||
Sender
|
Sender
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Messages from where this filter was originated
|
||||||
|
/// </summary>
|
||||||
|
public enum FilterOrigin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// None, empty filter
|
||||||
|
/// </summary>
|
||||||
|
None,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// From <see cref="Attributes.UpdateHandlerAttribute{T}"/> update validator filter
|
||||||
|
/// </summary>
|
||||||
|
Validator,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// From <see cref="Attributes.StateKeeperAttribute{TKey, TState, TKeeper}"/> state machine filter
|
||||||
|
/// </summary>
|
||||||
|
StateKeeper,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// From regular <see cref="Attributes.UpdateFilterAttribute{T}"/>
|
||||||
|
/// </summary>
|
||||||
|
Regualr
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Levels of debug writing
|
/// Levels of debug writing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -101,4 +128,5 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
HandlersPool = 0x8
|
HandlersPool = 0x8
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
using System.ComponentModel;
|
using Telegram.Bot.Polling;
|
||||||
using System.Threading;
|
using Telegram.Bot.Types;
|
||||||
using Telegram.Bot.Polling;
|
|
||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.Filters.Components;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
using Telegrator.Polling;
|
|
||||||
|
|
||||||
namespace Telegrator.Handlers.Components
|
namespace Telegrator.Handlers.Components
|
||||||
{
|
{
|
||||||
@@ -102,5 +100,20 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
protected abstract Task<Result> ExecuteInternal(IHandlerContainer container, CancellationToken cancellationToken);
|
protected abstract Task<Result> ExecuteInternal(IHandlerContainer container, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles failed filters during handler describing.
|
||||||
|
/// Use <see cref="Result"/> to control how router should treat this fail.
|
||||||
|
/// <see cref="Result.Ok"/> to silently continue decribing.
|
||||||
|
/// <see cref="Result.Fault"/> to stop\break decribing sequence.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <param name="failedFilter"></param>
|
||||||
|
/// <param name="origin"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual Task<Result> FiltersFallback(FilterExecutionContext<Update> context, IFilter<Update> failedFilter, FilterOrigin origin)
|
||||||
|
{
|
||||||
|
return Task.FromResult(Result.Ok());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
namespace Telegrator.Handlers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents handler results, allowing to communicate with router and control aspect execution
|
|
||||||
/// </summary>
|
|
||||||
public sealed class Result
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Is result positive
|
|
||||||
/// </summary>
|
|
||||||
public bool Positive { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Should router search for next matching handler
|
|
||||||
/// </summary>
|
|
||||||
public bool RouteNext { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Exact type that router should search
|
|
||||||
/// </summary>
|
|
||||||
public Type? NextType { get; }
|
|
||||||
|
|
||||||
internal Result(bool positive, bool routeNext, Type? nextType)
|
|
||||||
{
|
|
||||||
Positive = positive;
|
|
||||||
RouteNext = routeNext;
|
|
||||||
NextType = nextType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// "OK" result
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Result Ok()
|
|
||||||
=> new Result(true, false, null);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// "Somethong went wrong" result
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Result Fault()
|
|
||||||
=> new Result(false, false, null);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// "Search next handler" result
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Result Next()
|
|
||||||
=> new Result(true, true, null);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// "Search next handler of type" result
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Result Next<T>()
|
|
||||||
=> new Result(true, true, typeof(T));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using Telegrator.Aspects;
|
using Telegrator.Aspects;
|
||||||
using Telegrator.Handlers;
|
|
||||||
using Telegrator.Handlers.Components;
|
using Telegrator.Handlers.Components;
|
||||||
|
|
||||||
namespace Telegrator.MadiatorCore.Descriptors
|
namespace Telegrator.MadiatorCore.Descriptors
|
||||||
|
|||||||
@@ -41,14 +41,18 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
/// Validates the filter context using all filters in the set.
|
/// Validates the filter context using all filters in the set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filterContext">The filter execution context.</param>
|
/// <param name="filterContext">The filter execution context.</param>
|
||||||
|
/// <param name="failedFilter"></param>
|
||||||
|
/// <param name="origin"></param>
|
||||||
/// <returns>True if all filters pass; otherwise, false.</returns>
|
/// <returns>True if all filters pass; otherwise, false.</returns>
|
||||||
public bool Validate(FilterExecutionContext<Update> filterContext)
|
public bool Validate(FilterExecutionContext<Update> filterContext, out IFilter<Update> failedFilter, out FilterOrigin origin)
|
||||||
{
|
{
|
||||||
if (UpdateValidator != null)
|
if (UpdateValidator != null)
|
||||||
{
|
{
|
||||||
if (!UpdateValidator.CanPass(filterContext))
|
if (!UpdateValidator.CanPass(filterContext))
|
||||||
{
|
{
|
||||||
Alligator.LogDebug("(E) UpdateValidator filter of {0} for Update ({1}) didnt pass!", filterContext.Data["handler_name"], filterContext.Update.Id);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +65,8 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
if (!StateKeeperValidator.CanPass(filterContext))
|
if (!StateKeeperValidator.CanPass(filterContext))
|
||||||
{
|
{
|
||||||
Alligator.LogDebug("(E) StateKeeperValidator filter of {0} for Update ({1}) didnt pass!", filterContext.Data["handler_name"], filterContext.Update.Id);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,6 +83,8 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter)
|
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);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +93,8 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failedFilter = null!;
|
||||||
|
origin = FilterOrigin.None;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Telegrator.Handlers;
|
using Telegrator.Logging;
|
||||||
using Telegrator.Logging;
|
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
|
|
||||||
|
|||||||
@@ -215,11 +215,18 @@ namespace Telegrator.Polling
|
|||||||
{ "handler_name", descriptor.ToString() }
|
{ "handler_name", descriptor.ToString() }
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterExecutionContext<Update> filterContext = new FilterExecutionContext<Update>(_botInfo, update, update, data, []);
|
|
||||||
if (descriptor.Filters != null && !descriptor.Filters.Validate(filterContext))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
UpdateHandlerBase handlerInstance = provider.GetHandlerInstance(descriptor, cancellationToken);
|
UpdateHandlerBase handlerInstance = provider.GetHandlerInstance(descriptor, cancellationToken);
|
||||||
|
|
||||||
|
FilterExecutionContext<Update> filterContext = new FilterExecutionContext<Update>(_botInfo, update, update, data, []);
|
||||||
|
if (descriptor.Filters != null && !descriptor.Filters.Validate(filterContext, out IFilter<Update> 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);
|
return new DescribedHandlerInfo(descriptor, this, AwaitingProvider, client, handlerInstance, filterContext, descriptor.DisplayString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,5 +273,7 @@ namespace Telegrator.Polling
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class BreakDescribingException : Exception { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegrator.Aspects;
|
||||||
|
using Telegrator.Handlers.Components;
|
||||||
|
using Telegrator.Filters.Components;
|
||||||
|
using Telegrator.MadiatorCore;
|
||||||
|
|
||||||
|
namespace Telegrator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents handler results, allowing to communicate with router and control aspect execution
|
||||||
|
/// </summary>
|
||||||
|
public sealed class Result
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Is result positive
|
||||||
|
/// </summary>
|
||||||
|
public bool Positive { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should router search for next matching handler
|
||||||
|
/// </summary>
|
||||||
|
public bool RouteNext { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exact type that router should search
|
||||||
|
/// </summary>
|
||||||
|
public Type? NextType { get; }
|
||||||
|
|
||||||
|
internal Result(bool positive, bool routeNext, Type? nextType)
|
||||||
|
{
|
||||||
|
Positive = positive;
|
||||||
|
RouteNext = routeNext;
|
||||||
|
NextType = nextType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents 'success'
|
||||||
|
/// <list type="bullet">
|
||||||
|
/// <item>Inside <see cref="IPreProcessor"/> - let handler's main block be executed</item>
|
||||||
|
/// <item>Inside <see cref="UpdateHandlerBase.FiltersFallback(FilterExecutionContext{Update}, IFilter{Update}, FilterOrigin)"/> - let router continue describing</item>
|
||||||
|
/// <item>Inside <see cref="UpdateHandlerBase.ExecuteInternal(IHandlerContainer, CancellationToken)"/> - tells <see cref="IUpdateRouter"/> that he can stop describing, as needed handler was found</item>
|
||||||
|
/// </list>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Result Ok()
|
||||||
|
=> new Result(true, false, null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents 'fault' or 'error'. Use cases:
|
||||||
|
/// <list type="bullet">
|
||||||
|
/// <item>Inside <see cref="IPreProcessor"/> - interupts execution of handler, main block and <see cref="IPostProcessor"/> wont be executed</item>
|
||||||
|
/// <item>Inside <see cref="UpdateHandlerBase.FiltersFallback(FilterExecutionContext{Update}, IFilter{Update}, FilterOrigin)"/> - interupts router's describing sequence</item>
|
||||||
|
/// </list>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Result Fault()
|
||||||
|
=> new Result(false, false, null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents 'continue'. Use cases:
|
||||||
|
/// <list type="bullet">
|
||||||
|
/// <item>Inside <see cref="UpdateHandlerBase.ExecuteInternal(IHandlerContainer, CancellationToken)"/> - Tells <see cref="IUpdateRouter"/> to continue describing handlers</item>
|
||||||
|
/// </list>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Result Next()
|
||||||
|
=> new Result(true, true, null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents 'chain'. Use cases:
|
||||||
|
/// <list type="bullet">
|
||||||
|
/// <item>Inside <see cref="UpdateHandlerBase.ExecuteInternal(IHandlerContainer, CancellationToken)"/> - Tells <see cref="IUpdateRouter"/> to continue describing handlers and execute only handlers of exact type</item>
|
||||||
|
/// </list>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Result Next<T>()
|
||||||
|
=> new Result(true, true, typeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<EnableNETAnalyzers>True</EnableNETAnalyzers>
|
<EnableNETAnalyzers>True</EnableNETAnalyzers>
|
||||||
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
<Version>1.0.10</Version>
|
<Version>1.0.11</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user