Skip to content

Commit 9ea219e

Browse files
Merge pull request #35 from thygesteffensen/refactor/exception
Refactor/exception
2 parents be4eb8c + f88c098 commit 9ea219e

File tree

10 files changed

+56
-67
lines changed

10 files changed

+56
-67
lines changed

PowerAutomateMockUp/ExpressionParser/ExpressionGrammar.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ public class ExpressionGrammar
1414
public ExpressionGrammar(IEnumerable<IFunction> functions)
1515
{
1616
var functionCollection = functions ?? throw new ArgumentNullException(nameof(functions));
17-
// TODO: Go through parsers and reflect on the generic type. 1) Should they all be the same?
1817

1918
#region BasicAuxParsers
2019

@@ -31,8 +30,7 @@ public ExpressionGrammar(IEnumerable<IFunction> functions)
3130
Parse.AnyChar.Except(Parse.Char('@')).Except(Parse.Char('(').Except(Parse.Char(')'))).AtLeastOnce()
3231
.Text().Select(x => new ConstantRule(new ValueContainer(x)));
3332

34-
Parser<char> escapedCharacters
35-
= // TODO: Figure out which characters are escaped and where they are escaped -> simpleString or allowedString?
33+
Parser<char> escapedCharacters =
3634
from c in
3735
Parse.String("''").Select(n => '\'')
3836
.Or(Parse.String("''").Select(n => '\''))
@@ -43,14 +41,11 @@ from content in Parse.CharExcept('\'').Or(escapedCharacters).Many().Text()
4341
.Contained(Parse.Char('\''), Parse.Char('\''))
4442
select new StringLiteralRule(new ValueContainer(content));
4543

46-
Parser<string> allowedCharacters = // TODO: Verify valid characters
47-
Parse.Char('.')
48-
.Or(Parse.Char(','))
49-
.Or(Parse.Char('-'))
50-
.Or(Parse.String("@@").Select(_ => '@'))
51-
.Or(Parse.Char('@')).Except(Parse.String("@{"))
52-
.Or(Parse.Char(' '))
53-
.Select(character => character.ToString());
44+
Parser<string> allowedCharacters =
45+
Parse.String("@@").Select(_ => '@')
46+
.Or(Parse.AnyChar)
47+
.Except(Parse.String("@{"))
48+
.Select(c => c.ToString());
5449

5550
#endregion
5651

@@ -133,7 +128,7 @@ public string EvaluateToString(string input)
133128

134129
return output.GetValue<string>();
135130
}
136-
131+
137132
public ValueContainer EvaluateToValueContainer(string input)
138133
{
139134
return _input.Parse(input);

PowerAutomateMockUp/ExpressionParser/Functions/Base/ActionExecutorFactory.cs renamed to PowerAutomateMockUp/FlowParser/ActionExecutors/ActionExecutorFactory.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using Microsoft.Extensions.DependencyInjection;
5-
using Parser.FlowParser.ActionExecutors;
65

7-
namespace Parser.ExpressionParser.Functions.Base
6+
namespace Parser.FlowParser.ActionExecutors
87
{
98
public interface IActionExecutorFactory
109
{

PowerAutomateMockUp/ExpressionParser/Functions/Base/ActionExecutorRegistration.cs renamed to PowerAutomateMockUp/FlowParser/ActionExecutors/ActionExecutorRegistration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
22

3-
namespace Parser.ExpressionParser.Functions.Base
3+
namespace Parser.FlowParser.ActionExecutors
44
{
55
public class ActionExecutorRegistration
66
{

PowerAutomateMockUp/FlowParser/ActionExecutors/Implementations/TerminateActionExecutor.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Threading.Tasks;
44
using Microsoft.Extensions.Logging;
55
using Parser.ExpressionParser;
6-
using Parser.FlowParser.CustomExceptions;
76

87
namespace Parser.FlowParser.ActionExecutors.Implementations
98
{
@@ -34,7 +33,7 @@ public override Task<ActionResult> Execute()
3433
var exceptionMessage = "Terminate action with status: Failed.";
3534

3635
if (!Inputs.GetValue<Dictionary<string, ValueContainer>>()
37-
.TryGetValue("runError", out var runErrorDict)) throw new FlowRunnerException(exceptionMessage);
36+
.TryGetValue("runError", out var runErrorDict)) throw new PowerAutomateMockUpException(exceptionMessage);
3837

3938
var dict = runErrorDict.GetValue<Dictionary<string, ValueContainer>>();
4039

@@ -45,13 +44,13 @@ public override Task<ActionResult> Execute()
4544

4645
if (dict.TryGetValue("message", out var message))
4746
{
48-
exceptionMessage += $" Error code: {message}.";
47+
exceptionMessage += $" Error message: {message}.";
4948
}
5049

5150
_logger.LogInformation(
5251
$"Terminate Action {ActionName} reached with status {runStatus}. Error code: {code}. Error message: {message}. Throwing exception.");
5352

54-
throw new FlowRunnerException(exceptionMessage);
53+
throw new PowerAutomateMockUpException(exceptionMessage);
5554
default:
5655
throw new Exception($"Unknown runStatus: {runStatus}");
5756
}

PowerAutomateMockUp/FlowParser/CustomExceptions/FlowRunnerException.cs

Lines changed: 0 additions & 11 deletions
This file was deleted.

PowerAutomateMockUp/FlowParser/FlowRunner.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@ private async Task RunFlow()
112112
actionDescName = t.NextAction;
113113
}
114114

115-
if (currentAd == null && actionResult.ActionStatus == ActionStatus.Failed)
115+
if (currentAd == null && actionResultStatus == ActionStatus.Failed)
116116
{
117117
_logger.LogError(
118118
"No succeeding action found after last action had status: Failed. Throwing error.");
119-
throw actionResult.ActionExecutorException ??
119+
throw actionResult?.ActionExecutorException ??
120120
new PowerAutomateMockUpException(
121121
$"No exception recorded - {actionExecutor.ActionName} ended with status: Failed.");
122122
}
Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,11 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.IO;
4-
using Microsoft.Extensions.DependencyInjection;
5-
using Newtonsoft.Json;
1+
using System.Collections.Generic;
62

73
namespace Parser.FlowParser
84
{
95
public class FlowSettings
106
{
11-
12-
public Action<IServiceCollection> ServiceConfiguration { get; set; }
13-
147
public bool FailOnUnknownAction { get; set; } = true;
158

169
public List<string> IgnoreActions { get; set; } = new List<string>();
17-
18-
public Stream GetAsJsonStream()
19-
{
20-
var m = new MemoryStream();
21-
var w = new StreamWriter(m);
22-
using var writer = new JsonTextWriter(w);
23-
24-
var serializer = new JsonSerializer();
25-
26-
serializer.Serialize(writer, this);
27-
writer.Flush();
28-
m.Position = 0;
29-
return m;
30-
}
3110
}
3211
}

ReadMe.md

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ var path = "<path to flow definition>";
4949
// from Microsoft.Extensions.DependencyInjection
5050
var services = new ServiceCollection();
5151

52-
services.Configure<FlowSettings>(x => { }); // Optional way to add settings
53-
5452
// Required to set up required dependencies
5553
services.AddFlowRunner();
5654

@@ -65,6 +63,18 @@ await flowRunner.Trigger();
6563
// Your flow have now ran
6664
```
6765

66+
### Configuration
67+
This is optional and the settings class has the default values mentioned below.
68+
69+
The settings object is configured this way:
70+
```cs
71+
services.Configure<FlowSettings>(x => { }); // Optional way to add settings
72+
```
73+
The possbile values to set is:
74+
75+
* `x.FailOnUnknownAction` (default: `true`): If an action cannot be found and exception is thrown. This can be avoid and the action is ignored and the status is assumed to be `Succeeded`.
76+
* `x.IgnoreActions` (default: `empty`): List of action names which are ignored during exectuion, the action is not executed and the status is assumed to be `Succeeded`.
77+
6878
### Adding actions
6979
Actions can be added in three ways
7080

@@ -106,20 +116,39 @@ Currently there are two classes to extend, one is **DefaultBaseActionExecutor**
106116
```c#
107117
private class ActionExecutor : DefaultBaseActionExecutor
108118
{
109-
private readonly IState _state;
119+
private readonly IExpressionEngine _expression;
110120

111121
// Using dependency injection to get dependencies
112-
public TriggerActionExecutor(IState state)
122+
public TriggerActionExecutor(IExpressionEngine expression)
113123
{
114-
_state = state ?? throw new ArgumentNullException(nameof(state));
124+
_expression = expression ?? throw new ArgumentNullException(nameof(expression));
115125
}
116126

117127
public override Task<ActionResult> Execute()
118128
{
119-
// ... Execute action functionality
120-
121-
return Task.FromResult(
122-
new ActionResult {ActionStatus = ActionStatus.Succeeded});
129+
var result = new ActionResult();
130+
131+
try
132+
{
133+
// Some dangerous operation
134+
// ...
135+
136+
result.ActionOutput = new ValueContainer(new Dictionary<string, ValueContainer>()
137+
{
138+
{"Key", new ValueContainer("Value")}
139+
});
140+
// Corresponds to: outputs('<action>').Key || outputs('<action>')['Key']
141+
142+
result.ActionStatus = ActionStatus.Succeeded;
143+
}
144+
catch(EvenMoreDangerousException exp)
145+
{
146+
// PAMU handles the exceptions...
147+
result.ActionStatus = ActionStatus.Failed;
148+
result.ActionExecutorException = exp;
149+
}
150+
151+
return Task.FromResult(result);
123152
}
124153
}
125154
```
@@ -141,8 +170,7 @@ private class ActionExecutor : OpenApiConnectionActionExecutorBase
141170

142171
var entityName = parameters["string"].GetValue<string>();
143172

144-
return Task.FromResult(
145-
new ActionResult {ActionStatus = ActionStatus.Failed});
173+
// ...
146174
}
147175
}
148176
```

Test/ActionTests/TerminateActionTest.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using Parser.ExpressionParser.Functions.Base;
77
using Parser.FlowParser.ActionExecutors;
88
using Parser.FlowParser.ActionExecutors.Implementations;
9-
using Parser.FlowParser.CustomExceptions;
109

1110
namespace Test.ActionTests
1211
{
@@ -49,7 +48,7 @@ public void TerminateFailedNoMessageTest()
4948
"{\"Terminate\": { \"runAfter\": {}, \"type\": \"Terminate\", \"inputs\": { \"runStatus\": \"Failed\", \"runError\": { \"code\": \"1234\" } } } }";
5049
action.InitializeActionExecutor("TerminateAction", JToken.Parse(json).First.First);
5150

52-
var exception = Assert.ThrowsAsync<FlowRunnerException>(async () => { await action.Execute(); });
51+
var exception = Assert.ThrowsAsync<PowerAutomateMockUpException>(async () => { await action.Execute(); });
5352

5453
Assert.AreEqual("Terminate action with status: Failed. Error code: 1234.",exception.Message);
5554
}

Test/FullFlowTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ public override Task<ActionResult> Execute()
9999

100100
Console.WriteLine($"Email Title: {Parameters["NotificationEmailDefinition/notificationSubject"]}");
101101
Console.WriteLine($"Email Content: {Parameters["NotificationEmailDefinition/notificationBody"]}");
102+
102103
return Task.FromResult(new ActionResult {ActionOutput = new ValueContainer(true)});
103104
}
104105

0 commit comments

Comments
 (0)