diff --git a/src/modules/Elsa.Http/Activities/FlowSendHttpRequest.cs b/src/modules/Elsa.Http/Activities/FlowSendHttpRequest.cs
index 017a87803..afc2ce4d3 100644
--- a/src/modules/Elsa.Http/Activities/FlowSendHttpRequest.cs
+++ b/src/modules/Elsa.Http/Activities/FlowSendHttpRequest.cs
@@ -36,11 +36,17 @@ public class FlowSendHttpRequest : SendHttpRequestBase
await context.CompleteActivityWithOutcomesAsync(outcome);
}
+ ///
+ protected override async ValueTask HandleRequestExceptionAsync(ActivityExecutionContext context, HttpRequestException exception)
+ {
+ await context.CompleteActivityWithOutcomesAsync("Failed to connect");
+ }
+
private static ValueTask> GetExpectedStatusCodesOptionsAsync(PropertyInfo property, CancellationToken cancellationToken = default)
{
var options = new Dictionary
{
- [nameof(DynamicOutcomesOptions)] = new DynamicOutcomesOptions(new[]{"Unmatched status code", "Done"})
+ [nameof(DynamicOutcomesOptions)] = new DynamicOutcomesOptions(new[]{"Unmatched status code", "Failed to connect", "Done"})
};
return new(options);
diff --git a/src/modules/Elsa.Http/Activities/SendHttpRequest.cs b/src/modules/Elsa.Http/Activities/SendHttpRequest.cs
index cd966c245..eacbd0834 100644
--- a/src/modules/Elsa.Http/Activities/SendHttpRequest.cs
+++ b/src/modules/Elsa.Http/Activities/SendHttpRequest.cs
@@ -33,6 +33,11 @@ public class SendHttpRequest : SendHttpRequestBase
[Port]
public IActivity? UnmatchedStatusCode { get; set; }
+ ///
+ /// The activity to execute when the HTTP request fails to connect.
+ ///
+ public IActivity? FailedToConnect { get; set; }
+
///
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);
}
+ ///
+ protected override async ValueTask HandleRequestExceptionAsync(ActivityExecutionContext context, HttpRequestException exception)
+ {
+ await context.ScheduleActivityAsync(FailedToConnect, OnChildActivityCompletedAsync);
+ }
+
private async ValueTask OnChildActivityCompletedAsync(ActivityCompletedContext context)
{
await context.TargetContext.CompleteActivityAsync();
diff --git a/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs b/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs
index 59c5a5df2..b24161e83 100644
--- a/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs
+++ b/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs
@@ -84,6 +84,11 @@ public abstract class SendHttpRequestBase : Activity
///
protected abstract ValueTask HandleResponseAsync(ActivityExecutionContext context, HttpResponseMessage response);
+ ///
+ /// Handles an exception that occurred while sending the request.
+ ///
+ 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
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);