Skip to content

Commit 370fa1b

Browse files
committed
Adding null check for missing input step property name when loading definition from storage to give better error message.
1 parent cf00b12 commit 370fa1b

File tree

5 files changed

+43
-6
lines changed

5 files changed

+43
-6
lines changed

src/WorkflowCore/Services/DefinitionStorage/DefinitionLoader.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public DefinitionLoader(IWorkflowRegistry registry)
2525
{
2626
_registry = registry;
2727
}
28-
28+
2929
public WorkflowDefinition LoadDefinition(string source, Func<string, DefinitionSourceV1> deserializer)
3030
{
3131
var sourceObj = deserializer(source);
@@ -119,7 +119,7 @@ private WorkflowStepCollection ConvertSteps(ICollection<StepSourceV1> source, Ty
119119
targetStep.Outcomes.Add(new StepOutcome() { ExternalNextStepId = $"{nextStep.NextStepId}" });
120120

121121
result.Add(targetStep);
122-
122+
123123
i++;
124124
}
125125

@@ -176,6 +176,11 @@ private void AttachInputs(StepSourceV1 source, Type dataType, Type stepType, Wor
176176
var environmentVarsParameter = Expression.Parameter(typeof(IDictionary), "environment");
177177
var stepProperty = stepType.GetProperty(input.Key);
178178

179+
if (stepProperty == null)
180+
{
181+
throw new ArgumentException($"Unknown property for input {input.Key} on {source.Id}");
182+
}
183+
179184
if (input.Value is string)
180185
{
181186
var acn = BuildScalarInputAction(input, dataParameter, contextParameter, environmentVarsParameter, stepProperty);
@@ -203,7 +208,7 @@ private void AttachOutputs(StepSourceV1 source, Type dataType, Type stepType, Wo
203208

204209
var dataParameter = Expression.Parameter(dataType, "data");
205210
Expression targetProperty;
206-
211+
207212
// Check if our datatype has a matching property
208213
var propertyInfo = dataType.GetProperty(output.Key);
209214
if (propertyInfo != null)
@@ -217,7 +222,7 @@ private void AttachOutputs(StepSourceV1 source, Type dataType, Type stepType, Wo
217222
// If we did not find a matching property try to find a Indexer with string parameter
218223
propertyInfo = dataType.GetProperty("Item");
219224
targetProperty = Expression.Property(dataParameter, propertyInfo, Expression.Constant(output.Key));
220-
225+
221226
Action<IStepBody, object> acn = (pStep, pData) =>
222227
{
223228
object resolvedValue = sourceExpr.Compile().DynamicInvoke(pStep); ;

test/WorkflowCore.TestAssets/Utils.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace WorkflowCore.TestAssets
1010
public static class Utils
1111
{
1212
private static JsonSerializerSettings SerializerSettings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, DateFormatHandling = DateFormatHandling.IsoDateFormat, DateTimeZoneHandling = DateTimeZoneHandling.Utc };
13-
13+
1414
public static T DeepCopy<T>(T obj)
1515
{
1616
string str = JsonConvert.SerializeObject(obj, SerializerSettings);
@@ -32,6 +32,11 @@ public static string GetTestDefinitionDynamicJson()
3232
{
3333
return File.ReadAllText("stored-dynamic-definition.json");
3434
}
35+
36+
public static string GetTestDefinitionJsonInputExc()
37+
{
38+
return File.ReadAllText("stored-definition-input-exc.json");
39+
}
3540
}
3641
}
3742

test/WorkflowCore.TestAssets/WorkflowCore.TestAssets.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
<EmbeddedResource Include="stored-definition.json">
2626
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
2727
</EmbeddedResource>
28+
<EmbeddedResource Include="stored-definition-input-exc.json">
29+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
30+
</EmbeddedResource>
2831
</ItemGroup>
2932

3033
<ItemGroup>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"Id": "Test",
3+
"Version": 1,
4+
"Description": "",
5+
"DataType": "WorkflowCore.TestAssets.DataTypes.CounterBoard, WorkflowCore.TestAssets",
6+
"Steps": [
7+
{
8+
"Id": "Step1",
9+
"StepType": "WorkflowCore.TestAssets.Steps.Counter, WorkflowCore.TestAssets",
10+
"ErrorBehavior": "Retry",
11+
"Inputs": {
12+
"Value1": "data.Counter1"
13+
},
14+
"Outputs": {
15+
"Counter1": "step.Value"
16+
}
17+
}
18+
]
19+
}

test/WorkflowCore.UnitTests/Services/DefinitionStorage/DefinitionLoaderTests.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,18 @@ public void ParseDefinitionDynamic()
5959
A.CallTo(() => _registry.RegisterWorkflow(A<WorkflowDefinition>.That.Matches(MatchTestDefinition, ""))).MustHaveHappened();
6060
}
6161

62+
[Fact(DisplayName = "Should throw error for bad input property name on step")]
63+
public void ParseDefinitionInputException()
64+
{
65+
Assert.Throws<ArgumentException>(() => _subject.LoadDefinition(TestAssets.Utils.GetTestDefinitionJsonInputExc(), Deserializers.Json));
66+
}
6267

6368
private bool MatchTestDefinition(WorkflowDefinition def)
6469
{
6570
//TODO: make this better
6671
var step1 = def.Steps.Single(s => s.ExternalId == "Step1");
6772
var step2 = def.Steps.Single(s => s.ExternalId == "Step2");
68-
73+
6974
step1.Outcomes.Count.Should().Be(1);
7075
step1.Inputs.Count.Should().Be(1);
7176
step1.Outputs.Count.Should().Be(1);

0 commit comments

Comments
 (0)