diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ControlPanelTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ControlPanelTests.cs index 98618a0a..0332f812 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ControlPanelTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ControlPanelTests.cs @@ -46,7 +46,7 @@ protected async Task ExistingActionCanBeDeletedFromControlPanel(Task(controlPanel.Refresh()); + await Should.ThrowAsync(controlPanel.Refresh()); await store.GetFunction(functionId).ShouldBeNullAsync(); @@ -106,7 +106,7 @@ async Task(string _, Workflow workflow) => var controlPanel = await rFunc.ControlPanel(flowInstance).ShouldNotBeNullAsync(); await controlPanel.Delete(); - await Should.ThrowAsync(controlPanel.Refresh()); + await Should.ThrowAsync(controlPanel.Refresh()); await store.GetFunction(functionId).ShouldBeNullAsync(); diff --git a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ReInvocationTests.cs b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ReInvocationTests.cs index 988f7bbd..10525900 100644 --- a/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ReInvocationTests.cs +++ b/Core/Cleipnir.ResilientFunctions.Tests/TestTemplates/RFunctionTests/ReInvocationTests.cs @@ -342,7 +342,7 @@ protected async Task ReInvocationFailsWhenTheFunctionDoesNotExist(Task(() => controlPanel2.Restart()); + await Should.ThrowAsync(() => controlPanel2.Restart()); unhandledExceptionCatcher.ShouldNotHaveExceptions(); } diff --git a/Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/InvocationHelper.cs b/Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/InvocationHelper.cs index 854ef3e7..f5258fc0 100644 --- a/Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/InvocationHelper.cs +++ b/Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/InvocationHelper.cs @@ -251,7 +251,7 @@ public async Task PrepareForReInvocation(FlowId flowId, Re runningFunction.Dispose(); sf = await _functionStore.GetFunction(flowId); if (sf == null) - throw new UnexpectedFunctionState(flowId, $"Function '{flowId}' was not found"); + throw UnexpectedStateException.NotFound(flowId); await _functionStore.FailFunction( flowId, diff --git a/Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/Invoker.cs b/Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/Invoker.cs index 89a86528..8588c950 100644 --- a/Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/Invoker.cs +++ b/Core/Cleipnir.ResilientFunctions/CoreRuntime/Invocation/Invoker.cs @@ -215,7 +215,7 @@ private async Task PrepareForReInvocation(FlowId flowId, i { var restartedFunction = await _invocationHelper.RestartFunction(flowId, expectedEpoch); if (restartedFunction == null) - throw new UnexpectedFunctionState(flowId, $"Function '{flowId}' did not have expected epoch '{expectedEpoch}' on re-invocation"); + throw UnexpectedStateException.EpochMismatch(flowId); return await PrepareForReInvocation(flowId, restartedFunction); } @@ -289,7 +289,7 @@ private async Task PersistResultAndEnsureSuccess(FlowId flowId, Result try { await ScheduleRestart(flowId.Instance.Value, expectedEpoch); - } catch (UnexpectedFunctionState) {} //allow this exception - the invocation has been surpassed by other execution + } catch (UnexpectedStateException) {} //allow this exception - the invocation has been surpassed by other execution InvocationHelper.EnsureSuccess(flowId, result, allowPostponedOrSuspended); break; } diff --git a/Core/Cleipnir.ResilientFunctions/CoreRuntime/LeaseUpdater.cs b/Core/Cleipnir.ResilientFunctions/CoreRuntime/LeaseUpdater.cs index ebd00c29..4c2ed47e 100644 --- a/Core/Cleipnir.ResilientFunctions/CoreRuntime/LeaseUpdater.cs +++ b/Core/Cleipnir.ResilientFunctions/CoreRuntime/LeaseUpdater.cs @@ -68,12 +68,7 @@ private async Task Start() if (!success) { _disposed = true; - _unhandledExceptionHandler.Invoke( - new UnexpectedFunctionState( - _flowId, - $"{nameof(LeaseUpdater)} failed to update lease for executing function: '{_flowId}'" - ) - ); + _unhandledExceptionHandler.Invoke(UnexpectedStateException.LeaseUpdateFailed(_flowId)); } } catch (Exception e) @@ -82,7 +77,7 @@ private async Task Start() _unhandledExceptionHandler.Invoke( new FrameworkException( _flowId.Type, - $"{nameof(LeaseUpdater)} failed while executing function: '{_flowId}'", + $"{nameof(LeaseUpdater)} failed for '{_flowId}'", e ) ); diff --git a/Core/Cleipnir.ResilientFunctions/Domain/ControlPanel.cs b/Core/Cleipnir.ResilientFunctions/Domain/ControlPanel.cs index 2251b799..cfc04444 100644 --- a/Core/Cleipnir.ResilientFunctions/Domain/ControlPanel.cs +++ b/Core/Cleipnir.ResilientFunctions/Domain/ControlPanel.cs @@ -239,7 +239,7 @@ public async Task Refresh() { var sf = await _invocationHelper.GetFunction(FlowId); if (sf == null) - throw new UnexpectedFunctionState(FlowId, $"Function '{FlowId}' not found"); + throw UnexpectedStateException.NotFound(FlowId); Status = sf.Status; Epoch = sf.Epoch; diff --git a/Core/Cleipnir.ResilientFunctions/Domain/Exceptions/UnexpectedFunctionState.cs b/Core/Cleipnir.ResilientFunctions/Domain/Exceptions/UnexpectedFunctionState.cs deleted file mode 100644 index 61f769d3..00000000 --- a/Core/Cleipnir.ResilientFunctions/Domain/Exceptions/UnexpectedFunctionState.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace Cleipnir.ResilientFunctions.Domain.Exceptions; - -public sealed class UnexpectedFunctionState : FlowTypeException -{ - public FlowId FlowId { get; } - - public UnexpectedFunctionState(FlowId flowId, string message) - : base(flowId.Type, message) => FlowId = flowId; - - public UnexpectedFunctionState(FlowId flowId, string message, Exception innerException) - : base(flowId.Type, message, innerException) => FlowId = flowId; -} \ No newline at end of file diff --git a/Core/Cleipnir.ResilientFunctions/Domain/Exceptions/UnexpectedStateException.cs b/Core/Cleipnir.ResilientFunctions/Domain/Exceptions/UnexpectedStateException.cs new file mode 100644 index 00000000..24d3201d --- /dev/null +++ b/Core/Cleipnir.ResilientFunctions/Domain/Exceptions/UnexpectedStateException.cs @@ -0,0 +1,19 @@ +using System; +using Cleipnir.ResilientFunctions.CoreRuntime; + +namespace Cleipnir.ResilientFunctions.Domain.Exceptions; + +public sealed class UnexpectedStateException : FlowTypeException +{ + public FlowId FlowId { get; } + + public UnexpectedStateException(FlowId flowId, string message) + : base(flowId.Type, message) => FlowId = flowId; + + public UnexpectedStateException(FlowId flowId, string message, Exception innerException) + : base(flowId.Type, message, innerException) => FlowId = flowId; + + public static UnexpectedStateException NotFound(FlowId flowId) => new(flowId, $"{flowId} was not found"); + public static UnexpectedStateException EpochMismatch(FlowId flowId) => new(flowId, $"{flowId} did not have expected epoch at restart"); + public static UnexpectedStateException LeaseUpdateFailed(FlowId flowId) => new(flowId, $"{nameof(LeaseUpdater)} failed to update lease for '{flowId}'"); +} \ No newline at end of file diff --git a/Core/Cleipnir.ResilientFunctions/Messaging/MessageWriter.cs b/Core/Cleipnir.ResilientFunctions/Messaging/MessageWriter.cs index 48b141ef..dccb2567 100644 --- a/Core/Cleipnir.ResilientFunctions/Messaging/MessageWriter.cs +++ b/Core/Cleipnir.ResilientFunctions/Messaging/MessageWriter.cs @@ -59,7 +59,7 @@ public async Task AppendMessage(TMessage message, string? ide { await _scheduleReInvocation(_flowId.Instance.Value, expectedEpoch: epoch); } - catch (UnexpectedFunctionState) { } + catch (UnexpectedStateException) { } return Finding.Found; } diff --git a/Core/Cleipnir.ResilientFunctions/Messaging/MessagesPullerAndEmitter.cs b/Core/Cleipnir.ResilientFunctions/Messaging/MessagesPullerAndEmitter.cs index de03f502..70e2b49e 100644 --- a/Core/Cleipnir.ResilientFunctions/Messaging/MessagesPullerAndEmitter.cs +++ b/Core/Cleipnir.ResilientFunctions/Messaging/MessagesPullerAndEmitter.cs @@ -88,7 +88,7 @@ public async Task PullEvents(TimeSpan maxSinceLastSynced) var interruptCount = await _functionStore.GetInterruptCount(_flowId); if (interruptCount == null) - throw new UnexpectedFunctionState(_flowId, "Function was not found when fetching interrupt count"); + throw UnexpectedStateException.NotFound(_flowId); lock (_sync) _interruptCount = interruptCount.Value;