diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITaskDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITaskDefinitionBuilder.cs index b7dac41..c38f542 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITaskDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITaskDefinitionBuilder.cs @@ -92,6 +92,12 @@ public interface ITaskDefinitionBuilder /// The configured TBuilder Then(string directive); + /// + /// Configures the task to catch defined errors + /// + /// An used to setup the to use + /// The configured + TBuilder Catch(Action setup); } /// diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITryTaskDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITryTaskDefinitionBuilder.cs index 7105507..89c9372 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITryTaskDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITryTaskDefinitionBuilder.cs @@ -27,11 +27,4 @@ public interface ITryTaskDefinitionBuilder /// The configured ITryTaskDefinitionBuilder Do(Action setup); - /// - /// Configures the task to catch defined errors - /// - /// An used to setup the to use - /// The configured - ITryTaskDefinitionBuilder Catch(Action setup); - } diff --git a/src/ServerlessWorkflow.Sdk.Builders/TaskDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/TaskDefinitionBuilder.cs index 697e67b..5c75346 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/TaskDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/TaskDefinitionBuilder.cs @@ -54,6 +54,11 @@ public abstract class TaskDefinitionBuilder /// protected string? ThenDirective { get; set; } + /// + /// Gets/sets the definition of the catch node, if any + /// + protected ErrorCatcherDefinition? ErrorCatcher { get; set; } + /// public virtual TBuilder If(string condition) { @@ -126,6 +131,16 @@ public virtual TBuilder Then(string directive) return (TBuilder)(object)this; } + /// + public virtual TBuilder Catch(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new ErrorCatcherDefinitionBuilder(); + setup(builder); + this.ErrorCatcher = builder.Build(); + return (TBuilder)(object)this; + } + /// /// Applies the configuration common to all types of tasks /// @@ -143,6 +158,7 @@ protected virtual TDefinition Configure(TDefinition definition) definition.Input = this.Input; definition.Output = this.Output; definition.Export = this.Export; + definition.Catch = this.ErrorCatcher; return definition; } diff --git a/src/ServerlessWorkflow.Sdk.Builders/TryTaskDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/TryTaskDefinitionBuilder.cs index 2eb9566..9f96034 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/TryTaskDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/TryTaskDefinitionBuilder.cs @@ -25,11 +25,6 @@ public class TryTaskDefinitionBuilder /// protected Map? TryTasks { get; set; } - /// - /// Gets/sets the definition of the error catcher to use - /// - protected ErrorCatcherDefinition? ErrorCatcher { get; set; } - /// public virtual ITryTaskDefinitionBuilder Do(Action setup) { @@ -40,15 +35,6 @@ public virtual ITryTaskDefinitionBuilder Do(Action se return this; } - /// - public virtual ITryTaskDefinitionBuilder Catch(Action setup) - { - ArgumentNullException.ThrowIfNull(setup); - var builder = new ErrorCatcherDefinitionBuilder(); - this.ErrorCatcher = builder.Build(); - return this; - } - /// public override TryTaskDefinition Build() { diff --git a/src/ServerlessWorkflow.Sdk/Models/TaskDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/TaskDefinition.cs index f92e142..ce8f834 100644 --- a/src/ServerlessWorkflow.Sdk/Models/TaskDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/TaskDefinition.cs @@ -99,5 +99,10 @@ public virtual string? TimeoutReference [DataMember(Name = "metadata", Order = 15), JsonPropertyName("metadata"), JsonPropertyOrder(15), YamlMember(Alias = "metadata", Order = 15)] public virtual EquatableDictionary? Metadata { get; set; } + /// + /// Gets/sets the object used to define the errors to catch + /// + [DataMember(Name = "catch", Order = 16), JsonPropertyName("catch"), JsonPropertyOrder(16), YamlMember(Alias = "catch", Order = 16)] + public virtual ErrorCatcherDefinition? Catch { get; set; } } diff --git a/src/ServerlessWorkflow.Sdk/Models/Tasks/TryTaskDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/Tasks/TryTaskDefinition.cs index fc12c88..33a14ce 100644 --- a/src/ServerlessWorkflow.Sdk/Models/Tasks/TryTaskDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/Tasks/TryTaskDefinition.cs @@ -37,6 +37,6 @@ public record TryTaskDefinition /// [Required] [DataMember(Name = "catch", Order = 2), JsonPropertyName("catch"), JsonPropertyOrder(2), YamlMember(Alias = "catch", Order = 2)] - public required virtual ErrorCatcherDefinition Catch { get; set; } + public override ErrorCatcherDefinition? Catch { get; set; } } diff --git a/src/ServerlessWorkflow.Sdk/Validation/ErrorCatcherDefinitionValidator.cs b/src/ServerlessWorkflow.Sdk/Validation/ErrorCatcherDefinitionValidator.cs new file mode 100644 index 0000000..234c90f --- /dev/null +++ b/src/ServerlessWorkflow.Sdk/Validation/ErrorCatcherDefinitionValidator.cs @@ -0,0 +1,69 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using FluentValidation; +using ServerlessWorkflow.Sdk.Models; +using ServerlessWorkflow.Sdk.Properties; + +namespace ServerlessWorkflow.Sdk.Validation; + +/// +/// Represents the used to validate s +/// +public class ErrorCatcherDefinitionValidator + : AbstractValidator +{ + + /// + public ErrorCatcherDefinitionValidator(IServiceProvider serviceProvider, ComponentDefinitionCollection? components) + { + this.ServiceProvider = serviceProvider; + this.Components = components; + this.RuleFor(e => e) + .Must(HaveValidHandlers) + .WithMessage("The catch node must define either a 'do' section or a retry policy"); + this.RuleForEach(e => e.Do) + .SetValidator(e => new TaskMapEntryValidator(this.ServiceProvider, this.Components, e.Do?.ToDictionary(kvp => kvp.Key, kvp => kvp.Value))) + .When(e => e.Do != null); + this.RuleFor(e => e.RetryReference!) + .Must(ReferenceAnExistingRetryPolicy) + .When(e => !string.IsNullOrWhiteSpace(e.RetryReference)); + } + + /// + /// Gets the current + /// + protected IServiceProvider ServiceProvider { get; } + + /// + /// Gets the configured reusable components + /// + protected ComponentDefinitionCollection? Components { get; } + + /// + /// Determines whether the error catcher has valid handlers (either 'do' tasks or a retry policy) + /// + /// The error catcher to validate + /// A boolean indicating whether the error catcher has valid handlers + protected virtual bool HaveValidHandlers(ErrorCatcherDefinition catcher) + { + return (catcher.Do != null && catcher.Do.Count > 0) || catcher.Retry != null || !string.IsNullOrWhiteSpace(catcher.RetryReference); + } + + /// + /// Determines whether or not the specified retry policy is defined + /// + /// The name of the retry policy to check + /// A boolean indicating whether or not the specified retry policy is defined + protected virtual bool ReferenceAnExistingRetryPolicy(string name) => this.Components?.Retries?.ContainsKey(name) == true; +} diff --git a/src/ServerlessWorkflow.Sdk/Validation/TaskDefinitionValidator.cs b/src/ServerlessWorkflow.Sdk/Validation/TaskDefinitionValidator.cs index 1d93519..12b68ef 100644 --- a/src/ServerlessWorkflow.Sdk/Validation/TaskDefinitionValidator.cs +++ b/src/ServerlessWorkflow.Sdk/Validation/TaskDefinitionValidator.cs @@ -39,6 +39,9 @@ public TaskDefinitionValidator(IServiceProvider serviceProvider, ComponentDefini .Must(ReferenceAnExistingTimeout) .When(t => !string.IsNullOrWhiteSpace(t.TimeoutReference)) .WithMessage(ValidationErrors.UndefinedTimeout); + this.RuleFor(t => t.Catch!) + .SetValidator(t => new ErrorCatcherDefinitionValidator(this.ServiceProvider, this.Components)) + .When(t => t.Catch != null); this.When(t => t is CallTaskDefinition, () => { this.RuleFor(t => (CallTaskDefinition)t) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy