Skip to content

Commit

Permalink
Exception refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
stidsborg committed Aug 7, 2024
1 parent 2c99127 commit 9074e40
Show file tree
Hide file tree
Showing 18 changed files with 65 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public async Task FunctionCanBeSuspendedForASecondSuccessfully()
await messages.SuspendFor(timeoutEventId: "timeout", resumeAfter: TimeSpan.FromSeconds(1));
});

await Should.ThrowAsync<FunctionInvocationSuspendedException>(rAction.Invoke(flowInstance.Value, "param"));
await Should.ThrowAsync<InvocationSuspendedException>(rAction.Invoke(flowInstance.Value, "param"));

await BusyWait.Until(() =>
store.GetFunction(functionId).SelectAsync(sf => sf?.Status == Status.Succeeded)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ protected async Task SecondInvocationFailsOnSuspendedFlow(Task<IFunctionStore> s
var secondInvocationTask = rFunc.Invoke(flowInstance.Value, param: "Hallo World");
await BusyWait.Until(() => secondInvocationTask.IsCompleted);

await Should.ThrowAsync<FunctionInvocationSuspendedException>(secondInvocationTask);
await Should.ThrowAsync<InvocationSuspendedException>(secondInvocationTask);

if (unhandledExceptionHandler.ThrownExceptions.Any())
throw new Exception("Unhandled exception occurred", unhandledExceptionHandler.ThrownExceptions[0]);
Expand Down Expand Up @@ -109,7 +109,7 @@ protected async Task SecondInvocationFailsOnPostponedFlow(Task<IFunctionStore> s
var secondInvocationTask = rFunc.Invoke(flowInstance.Value, param: "Hallo World");
await BusyWait.Until(() => secondInvocationTask.IsCompleted);

await Should.ThrowAsync<FunctionInvocationPostponedException>(secondInvocationTask);
await Should.ThrowAsync<InvocationPostponedException>(secondInvocationTask);

if (unhandledExceptionHandler.ThrownExceptions.Any())
throw new Exception("Unhandled exception occurred", unhandledExceptionHandler.ThrownExceptions[0]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public async Task FunctionIsSuspendedWhenAwaitedMessageDoesNotAlreadyExist(Task<
}
);

await Should.ThrowAsync<FunctionInvocationSuspendedException>(() =>
await Should.ThrowAsync<InvocationSuspendedException>(() =>
rAction.Invoke(functionId.Instance.Value, "")
);
var sf = await store.GetFunction(functionId);
Expand Down Expand Up @@ -105,7 +105,7 @@ public async Task TimeoutEventCausesSuspendedFunctionToBeReInvoked(Task<IFunctio
}
);

await Should.ThrowAsync<FunctionInvocationSuspendedException>(() =>
await Should.ThrowAsync<InvocationSuspendedException>(() =>
rFunc.Invoke(functionId.Instance.Value, "")
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ protected async Task PostponedFuncIsCompletedByWatchDog(Task<IFunctionStore> sto
(string _) => Postpone.For(1_000).ToResult<string>().ToTask()
).Invoke;

await Should.ThrowAsync<FunctionInvocationPostponedException>(() =>
await Should.ThrowAsync<InvocationPostponedException>(() =>
rFunc(param, param)
);
crashableStore.Crash();
Expand Down Expand Up @@ -88,7 +88,7 @@ protected async Task PostponedFuncWithStateIsCompletedByWatchDog(Task<IFunctionS
inner: (_, _) => throw new PostponeInvocationException(1_000)
).Invoke;

await Should.ThrowAsync<FunctionInvocationPostponedException>(() => rFunc(param, param));
await Should.ThrowAsync<InvocationPostponedException>(() => rFunc(param, param));
unhandledExceptionHandler.ShouldNotHaveExceptions();
}
{
Expand Down Expand Up @@ -168,7 +168,7 @@ protected async Task PostponedActionIsCompletedByWatchDog(Task<IFunctionStore> s
(string _) => Postpone.Until(DateTime.UtcNow.AddMilliseconds(1_000)).ToResult().ToTask()
).Invoke;

await Should.ThrowAsync<FunctionInvocationPostponedException>(() => rAction(flowInstance.Value, param));
await Should.ThrowAsync<InvocationPostponedException>(() => rAction(flowInstance.Value, param));
unhandledExceptionHandler.ShouldNotHaveExceptions();
}
{
Expand Down Expand Up @@ -214,7 +214,7 @@ protected async Task PostponedActionWithStateIsCompletedByWatchDog(Task<IFunctio
(string _, Workflow _) => Postpone.For(1_000).ToResult().ToTask()
).Invoke;

await Should.ThrowAsync<FunctionInvocationPostponedException>(() =>
await Should.ThrowAsync<InvocationPostponedException>(() =>
rAction(flowInstance.Value, param)
);
unhandledExceptionHandler.ShouldNotHaveExceptions();
Expand Down Expand Up @@ -274,7 +274,7 @@ protected async Task PostponedActionIsCompletedByWatchDogAfterCrash(Task<IFuncti
.Invoke;

var instanceId = functionId.Instance.ToString();
await Should.ThrowAsync<FunctionInvocationPostponedException>(() => _ = rFunc(instanceId, "param"));
await Should.ThrowAsync<InvocationPostponedException>(() => _ = rFunc(instanceId, "param"));
crashableStore.Crash();
}
{
Expand Down Expand Up @@ -314,7 +314,7 @@ protected async Task ThrownPostponeExceptionResultsInPostponedAction(Task<IFunct

//invoke
{
Should.Throw<FunctionInvocationPostponedException>(
Should.Throw<InvocationPostponedException>(
() => rAction.Invoke("invoke", "hello")
);
var (status, postponedUntil) = await store
Expand Down Expand Up @@ -351,7 +351,7 @@ await store.CreateFunction(
timestamp: DateTime.UtcNow.Ticks
).ShouldBeTrueAsync();

Should.Throw<FunctionInvocationPostponedException>(
Should.Throw<InvocationPostponedException>(
() => rAction.ControlPanel(functionId.Instance.Value).Result!.Restart()
);

Expand Down Expand Up @@ -404,7 +404,7 @@ protected async Task ThrownPostponeExceptionResultsInPostponedActionWithState(Ta
//invoke
{
var functionId = new FlowId(flowType, "invoke");
Should.Throw<FunctionInvocationPostponedException>(
Should.Throw<InvocationPostponedException>(
() => rAction.Invoke(functionId.Instance.Value, "hello")
);
var (status, postponedUntil) = await store.GetFunction(functionId).Map(sf => Tuple.Create(sf?.Status, sf?.PostponedUntil));
Expand Down Expand Up @@ -438,7 +438,7 @@ await store.CreateFunction(
timestamp: DateTime.UtcNow.Ticks
).ShouldBeTrueAsync();

Should.Throw<FunctionInvocationPostponedException>(
Should.Throw<InvocationPostponedException>(
() => rAction.ControlPanel(functionId.Instance).Result!.Restart()
);

Expand Down Expand Up @@ -489,7 +489,7 @@ protected async Task ThrownPostponeExceptionResultsInPostponedFunc(Task<IFunctio

//invoke
{
Should.Throw<FunctionInvocationPostponedException>(
Should.Throw<InvocationPostponedException>(
() => rFunc.Invoke("invoke", "hello")
);
var (status, postponedUntil) = await store
Expand Down Expand Up @@ -527,7 +527,7 @@ await store.CreateFunction(
timestamp: DateTime.UtcNow.Ticks
).ShouldBeTrueAsync();
var controlPanel = await rFunc.ControlPanel(functionId.Instance).ShouldNotBeNullAsync();
Should.Throw<FunctionInvocationPostponedException>(() => controlPanel.Restart());
Should.Throw<InvocationPostponedException>(() => controlPanel.Restart());

var (status, postponedUntil) = await store.GetFunction(functionId).Map(sf => Tuple.Create(sf?.Status, sf?.PostponedUntil));
status.ShouldBe(Status.Postponed);
Expand Down Expand Up @@ -578,7 +578,7 @@ protected async Task ThrownPostponeExceptionResultsInPostponedFuncWithState(Task
//invoke
{
var functionId = new FlowId(flowType, "invoke");
Should.Throw<FunctionInvocationPostponedException>(
Should.Throw<InvocationPostponedException>(
() => rFunc.Invoke(functionId.Instance.Value, "hello")
);
var (status, postponedUntil) = await store.GetFunction(functionId).Map(sf => Tuple.Create(sf?.Status, sf?.PostponedUntil));
Expand Down Expand Up @@ -614,7 +614,7 @@ await store.CreateFunction(
).ShouldBeTrueAsync();

var controlPanel = await rFunc.ControlPanel(functionId.Instance).ShouldNotBeNullAsync();
Should.Throw<FunctionInvocationPostponedException>(() => controlPanel.Restart());
Should.Throw<InvocationPostponedException>(() => controlPanel.Restart());

var (status, postponedUntil) = await store.GetFunction(functionId).Map(sf => Tuple.Create(sf?.Status, sf?.PostponedUntil));
status.ShouldBe(Status.Postponed);
Expand Down Expand Up @@ -819,7 +819,7 @@ protected async Task WorkflowDelayInvocationDelaysFunction(Task<IFunctionStore>
(string _, Workflow workflow) => workflow.Delay("Delay", TimeSpan.FromDays(1))
);

await Should.ThrowAsync<FunctionInvocationPostponedException>(
await Should.ThrowAsync<InvocationPostponedException>(
() => rFunc.Invoke(functionId.Instance.Value, "test")
);

Expand Down Expand Up @@ -848,7 +848,7 @@ protected async Task WorkflowDelayWithDateTimeInvocationDelaysFunction(Task<IFun
(string _, Workflow workflow) => workflow.Delay("Delay", tomorrow)
);

await Should.ThrowAsync<FunctionInvocationPostponedException>(
await Should.ThrowAsync<InvocationPostponedException>(
() => registration.Invoke(functionId.Instance.Value, "test")
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ protected async Task ActionCanBeSuspended(Task<IFunctionStore> storeTask)
Task<Result> (string _) => throw new SuspendInvocationException(expectedInterruptCount: new InterruptCount(0))
);

await Should.ThrowAsync<FunctionInvocationSuspendedException>(
await Should.ThrowAsync<InvocationSuspendedException>(
() => rAction.Invoke(flowInstance.Value, "hello world")
);

Expand Down Expand Up @@ -68,7 +68,7 @@ protected async Task FunctionCanBeSuspended(Task<IFunctionStore> storeTask)
Task<Result<string>>(string _) => Suspend.While(0).ToResult<string>().ToTask()
);

await Should.ThrowAsync<FunctionInvocationSuspendedException>(
await Should.ThrowAsync<InvocationSuspendedException>(
() => rFunc.Invoke(instanceId.Value, "hello world")
);

Expand Down Expand Up @@ -113,7 +113,7 @@ protected async Task DetectionOfEligibleSuspendedFunctionSucceedsAfterEventAdded
return Result.SucceedWithValue("completed").ToTask();
});

await Should.ThrowAsync<FunctionInvocationSuspendedException>(
await Should.ThrowAsync<InvocationSuspendedException>(
() => rFunc.Invoke(flowInstance.Value, "hello world")
);

Expand Down Expand Up @@ -156,7 +156,7 @@ protected async Task PostponedFunctionIsResumedAfterEventIsAppendedToMessages(Ta
return Result.SucceedWithValue("completed").ToTask();
});

await Should.ThrowAsync<FunctionInvocationPostponedException>(
await Should.ThrowAsync<InvocationPostponedException>(
() => rFunc.Invoke(flowInstance.Value, "hello world")
);

Expand Down Expand Up @@ -195,7 +195,7 @@ protected async Task EligibleSuspendedFunctionIsPickedUpByWatchdog(Task<IFunctio
return Suspend.While(0).ToResult<string>().ToTask();
});

await Should.ThrowAsync<FunctionInvocationSuspendedException>(
await Should.ThrowAsync<InvocationSuspendedException>(
() => rFunc.Invoke(flowInstance, "hello world")
);

Expand Down Expand Up @@ -231,7 +231,7 @@ async Task<string> (string param, Workflow workflow) =>
}
);

await Should.ThrowAsync<FunctionInvocationSuspendedException>(() =>
await Should.ThrowAsync<InvocationSuspendedException>(() =>
registration.Invoke(flowInstance, "hello world")
);

Expand Down Expand Up @@ -277,7 +277,7 @@ async Task<string> (string param, Workflow workflow) =>
}
);

await Should.ThrowAsync<FunctionInvocationSuspendedException>(() =>
await Should.ThrowAsync<InvocationSuspendedException>(() =>
registration.Invoke(flowInstance.Value, "hello world")
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ public async Task<TReturn> WaitForFunctionResult(FlowId flowId, bool allowPostpo
throw new PreviousInvocationException(flowId, error);
case Status.Postponed:
if (allowPostponedAndSuspended) { await Task.Delay(250); continue;}
throw new FunctionInvocationPostponedException(
throw new InvocationPostponedException(
flowId,
postponedUntil: new DateTime(storedFunction.PostponedUntil!.Value, DateTimeKind.Utc)
);
case Status.Suspended:
if (allowPostponedAndSuspended) { await Task.Delay(250); continue; }
throw new FunctionInvocationSuspendedException(flowId);
throw new InvocationSuspendedException(flowId);
default:
throw new ArgumentOutOfRangeException();
}
Expand Down Expand Up @@ -196,14 +196,14 @@ public static void EnsureSuccess(FlowId flowId, Result<TReturn> result, bool all
if (allowPostponedOrSuspended)
return;
else
throw new FunctionInvocationPostponedException(flowId, result.Postpone!.DateTime);
throw new InvocationPostponedException(flowId, result.Postpone!.DateTime);
case Outcome.Fail:
throw result.Fail!;
case Outcome.Suspend:
if (allowPostponedOrSuspended)
return;
else
throw new FunctionInvocationSuspendedException(flowId);
throw new InvocationSuspendedException(flowId);
default:
throw new ArgumentOutOfRangeException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ namespace Cleipnir.ResilientFunctions.CoreRuntime;

public class UnhandledExceptionHandler
{
private readonly Action<RFunctionException> _exceptionHandler;
private readonly Action<FlowTypeException> _exceptionHandler;

public UnhandledExceptionHandler(Action<RFunctionException> exceptionHandler)
public UnhandledExceptionHandler(Action<FlowTypeException> exceptionHandler)
=> _exceptionHandler = exceptionHandler;

public void Invoke(RFunctionException exception) => SafeTry(() => _exceptionHandler(exception));
public void Invoke(FlowTypeException exception) => SafeTry(() => _exceptionHandler(exception));

public void Invoke(FlowType flowType, Exception exception)
{
if (exception is RFunctionException re)
if (exception is FlowTypeException re)
Invoke(re);
else
Invoke(new FrameworkException(flowType, "Unhandled exception", exception));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Cleipnir.ResilientFunctions.Domain.Exceptions;

public sealed class ConcurrentModificationException : RFunctionException
public sealed class ConcurrentModificationException : FlowTypeException
{
public FlowId FlowId { get; }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Cleipnir.ResilientFunctions.Domain.Exceptions;

public class EffectException : RFunctionException
public class EffectException : FlowTypeException
{
public FlowId FlowId { get; }
public PreviouslyThrownException Exception { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

namespace Cleipnir.ResilientFunctions.Domain.Exceptions;

public abstract class RFunctionException : Exception
public abstract class FlowTypeException : Exception
{
public FlowType FlowType { get; }

public RFunctionException(FlowType flowType, string message)
public FlowTypeException(FlowType flowType, string message)
: base(message) => FlowType = flowType;

public RFunctionException(FlowType flowType, string message, Exception innerException)
public FlowTypeException(FlowType flowType, string message, Exception innerException)
: base(message, innerException) => FlowType = flowType;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Cleipnir.ResilientFunctions.Domain.Exceptions;

public sealed class FrameworkException : RFunctionException
public sealed class FrameworkException : FlowTypeException
{
public FrameworkException(FlowType flowType, string message)
: base(flowType, message) {}
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;

namespace Cleipnir.ResilientFunctions.Domain.Exceptions;

public sealed class InvocationPostponedException(FlowId flowId, DateTime postponedUntil)
: FlowTypeException(flowId.Type, $"{flowId} has been postponed until: '{postponedUntil:O}'")
{
public FlowId FlowId { get; } = flowId;
public DateTime PostponedUntil { get; } = postponedUntil;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Cleipnir.ResilientFunctions.Domain.Exceptions;

public sealed class InvocationSuspendedException(FlowId flowId)
: FlowTypeException(flowId.Type, $"{flowId} invocation has been suspended")
{
public FlowId FlowId { get; } = flowId;
}
Loading

0 comments on commit 9074e40

Please sign in to comment.