Skip to content

Commit 2c1ee61

Browse files
authored
Merge branch 'main' into wangbill/dedup
2 parents 81bcd66 + f505eac commit 2c1ee61

File tree

4 files changed

+108
-6
lines changed

4 files changed

+108
-6
lines changed

src/Analyzers/AnalyzerReleases.Shipped.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
; Shipped analyzer releases
22
; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
33

4+
## Release 0.2.0
5+
6+
### New Rules
7+
8+
Rule ID | Category | Severity | Notes
9+
--------|----------|----------|-------
10+
DURABLE2003 | Activity | Warning | **FunctionNotFoundAnalyzer**: Warns when an activity function call references a name that does not match any defined activity in the compilation.
11+
DURABLE2004 | Orchestration | Warning | **FunctionNotFoundAnalyzer**: Warns when a sub-orchestration call references a name that does not match any defined orchestrator in the compilation.
12+
413
## Release 0.1.0
514

615
### New Rules

src/Analyzers/AnalyzerReleases.Unshipped.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,4 @@
44
### New Rules
55

66
Rule ID | Category | Severity | Notes
7-
--------|----------|----------|-------
8-
DURABLE2003 | Activity | Warning | **FunctionNotFoundAnalyzer**: Warns when an activity function call references a name that does not match any defined activity in the compilation.
9-
DURABLE2004 | Orchestration | Warning | **FunctionNotFoundAnalyzer**: Warns when a sub-orchestration call references a name that does not match any defined orchestrator in the compilation.
7+
--------|----------|----------|-------

src/Analyzers/Analyzers.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
</PropertyGroup>
1212

1313
<PropertyGroup>
14-
<VersionPrefix>0.1.0</VersionPrefix>
14+
<VersionPrefix>0.2.0</VersionPrefix>
1515
<VersionSuffix></VersionSuffix>
1616
<PackageDescription>.NET Analyzers for the Durable Task SDK.</PackageDescription>
1717
<NeutralLanguage>en</NeutralLanguage>

test/Grpc.IntegrationTests/OrchestrationPatterns.cs

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,101 @@ async Task<int> OrchestratorFunc(TaskOrchestrationContext ctx, int counter)
11951195
Assert.Equal(EventCount, metadata.ReadOutputAs<int>());
11961196
}
11971197

1198-
// TODO: Test for multiple external events with the same name
1199-
// TODO: Test for catching activity exceptions of specific types
1198+
[Fact]
1199+
public async Task CatchingActivityExceptionsByType()
1200+
{
1201+
TaskName orchestratorName = nameof(CatchingActivityExceptionsByType);
1202+
TaskName throwInvalidOpActivityName = "ThrowInvalidOp";
1203+
TaskName throwArgumentActivityName = "ThrowArgument";
1204+
TaskName successActivityName = "Success";
1205+
1206+
await using HostTestLifetime server = await this.StartWorkerAsync(b =>
1207+
{
1208+
b.AddTasks(tasks => tasks
1209+
.AddOrchestratorFunc(orchestratorName, async ctx =>
1210+
{
1211+
List<string> results = new();
1212+
1213+
// Test 1: Catch InvalidOperationException
1214+
try
1215+
{
1216+
await ctx.CallActivityAsync(throwInvalidOpActivityName);
1217+
results.Add("No exception thrown");
1218+
}
1219+
catch (TaskFailedException ex) when (ex.FailureDetails?.IsCausedBy<InvalidOperationException>() == true)
1220+
{
1221+
results.Add("Caught InvalidOperationException");
1222+
}
1223+
catch (TaskFailedException)
1224+
{
1225+
results.Add("Caught wrong exception type");
1226+
}
1227+
1228+
// Test 2: Catch ArgumentException
1229+
try
1230+
{
1231+
await ctx.CallActivityAsync(throwArgumentActivityName);
1232+
results.Add("No exception thrown");
1233+
}
1234+
catch (TaskFailedException ex) when (ex.FailureDetails?.IsCausedBy<ArgumentException>() == true)
1235+
{
1236+
results.Add("Caught ArgumentException");
1237+
}
1238+
catch (TaskFailedException)
1239+
{
1240+
results.Add("Caught wrong exception type");
1241+
}
1242+
1243+
// Test 3: Successful activity should not throw
1244+
try
1245+
{
1246+
string result = await ctx.CallActivityAsync<string>(successActivityName);
1247+
results.Add(result);
1248+
}
1249+
catch (TaskFailedException)
1250+
{
1251+
results.Add("Unexpected exception");
1252+
}
1253+
1254+
// Test 4: Catch with base Exception type
1255+
try
1256+
{
1257+
await ctx.CallActivityAsync(throwInvalidOpActivityName);
1258+
results.Add("No exception thrown");
1259+
}
1260+
catch (TaskFailedException ex) when (ex.FailureDetails?.IsCausedBy<Exception>() == true)
1261+
{
1262+
results.Add("Caught base Exception");
1263+
}
1264+
1265+
return results;
1266+
})
1267+
.AddActivityFunc(throwInvalidOpActivityName, (TaskActivityContext ctx) =>
1268+
{
1269+
throw new InvalidOperationException("Invalid operation");
1270+
})
1271+
.AddActivityFunc(throwArgumentActivityName, (TaskActivityContext ctx) =>
1272+
{
1273+
throw new ArgumentException("Invalid argument");
1274+
})
1275+
.AddActivityFunc<string>(successActivityName, (TaskActivityContext ctx) =>
1276+
{
1277+
return "Success";
1278+
}));
1279+
});
1280+
1281+
string instanceId = await server.Client.ScheduleNewOrchestrationInstanceAsync(orchestratorName);
1282+
OrchestrationMetadata metadata = await server.Client.WaitForInstanceCompletionAsync(
1283+
instanceId, getInputsAndOutputs: true, this.TimeoutToken);
1284+
Assert.NotNull(metadata);
1285+
Assert.Equal(OrchestrationRuntimeStatus.Completed, metadata.RuntimeStatus);
1286+
1287+
List<string>? results = metadata.ReadOutputAs<List<string>>();
1288+
Assert.NotNull(results);
1289+
Assert.Equal(4, results!.Count);
1290+
Assert.Equal("Caught InvalidOperationException", results[0]);
1291+
Assert.Equal("Caught ArgumentException", results[1]);
1292+
Assert.Equal("Success", results[2]);
1293+
Assert.Equal("Caught base Exception", results[3]);
1294+
}
12001295
}

0 commit comments

Comments
 (0)