Add request exception handling to SendHttpRequest activity

This commit is contained in:
Sipke Schoorstra 2023-09-10 21:31:57 +02:00
parent f6c4ffb934
commit a8b3cbab74
3 changed files with 29 additions and 7 deletions

View file

@ -36,11 +36,17 @@ public class FlowSendHttpRequest : SendHttpRequestBase
await context.CompleteActivityWithOutcomesAsync(outcome);
}
/// <inheritdoc />
protected override async ValueTask HandleRequestExceptionAsync(ActivityExecutionContext context, HttpRequestException exception)
{
await context.CompleteActivityWithOutcomesAsync("Failed to connect");
}
private static ValueTask<IDictionary<string, object>> GetExpectedStatusCodesOptionsAsync(PropertyInfo property, CancellationToken cancellationToken = default)
{
var options = new Dictionary<string, object>
{
[nameof(DynamicOutcomesOptions)] = new DynamicOutcomesOptions(new[]{"Unmatched status code", "Done"})
[nameof(DynamicOutcomesOptions)] = new DynamicOutcomesOptions(new[]{"Unmatched status code", "Failed to connect", "Done"})
};
return new(options);

View file

@ -33,6 +33,11 @@ public class SendHttpRequest : SendHttpRequestBase
[Port]
public IActivity? UnmatchedStatusCode { get; set; }
/// <summary>
/// The activity to execute when the HTTP request fails to connect.
/// </summary>
public IActivity? FailedToConnect { get; set; }
/// <inheritdoc />
protected override async ValueTask HandleResponseAsync(ActivityExecutionContext context, HttpResponseMessage response)
{
@ -41,15 +46,15 @@ public class SendHttpRequest : SendHttpRequestBase
var matchingCase = expectedStatusCodes.FirstOrDefault(x => x.StatusCode == statusCode);
var activity = matchingCase != null ? matchingCase.Activity : UnmatchedStatusCode;
if (activity == null)
{
await context.CompleteActivityAsync();
return;
}
await context.ScheduleActivityAsync(activity, OnChildActivityCompletedAsync);
}
/// <inheritdoc />
protected override async ValueTask HandleRequestExceptionAsync(ActivityExecutionContext context, HttpRequestException exception)
{
await context.ScheduleActivityAsync(FailedToConnect, OnChildActivityCompletedAsync);
}
private async ValueTask OnChildActivityCompletedAsync(ActivityCompletedContext context)
{
await context.TargetContext.CompleteActivityAsync();

View file

@ -84,6 +84,11 @@ public abstract class SendHttpRequestBase : Activity<HttpResponseMessage>
/// </summary>
protected abstract ValueTask HandleResponseAsync(ActivityExecutionContext context, HttpResponseMessage response);
/// <summary>
/// Handles an exception that occurred while sending the request.
/// </summary>
protected abstract ValueTask HandleRequestExceptionAsync(ActivityExecutionContext context, HttpRequestException exception);
private async Task TrySendAsync(ActivityExecutionContext context)
{
var request = PrepareRequest(context);
@ -100,6 +105,12 @@ public abstract class SendHttpRequestBase : Activity<HttpResponseMessage>
await HandleResponseAsync(context, response);
}
catch(HttpRequestException e)
{
context.AddExecutionLogEntry("Error", e.Message, payload: new { StackTrace = e.StackTrace });
context.JournalData.Add("Error", e.Message);
await HandleRequestExceptionAsync(context, e);
}
catch (TaskCanceledException e)
{
context.JournalData.Add("Cancelled", true);