Skip to content

Commit b4a522c

Browse files
authored
Add integration tests for exception type handling (#544)
1 parent 4c04e29 commit b4a522c

File tree

1 file changed

+97
-2
lines changed

1 file changed

+97
-2
lines changed

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)