diff --git a/src/Akka.Hosting.Tests/StartFailureSpec.cs b/src/Akka.Hosting.Tests/StartFailureSpec.cs new file mode 100644 index 0000000..032b27c --- /dev/null +++ b/src/Akka.Hosting.Tests/StartFailureSpec.cs @@ -0,0 +1,52 @@ +using System; +using System.Threading.Tasks; +using Akka.Actor; +using FluentAssertions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Xunit; +using Xunit.Abstractions; +using static FluentAssertions.FluentActions; + +namespace Akka.Hosting.Tests; + +public class StartFailureSpec +{ + private readonly ITestOutputHelper _output; + + public StartFailureSpec(ITestOutputHelper output) + { + _output = output; + } + + [Fact] + public async Task ShouldThrowWhenActorSystemFailedToStart() + { + // arrange + var host = new HostBuilder() + .ConfigureLogging(builder => + { + builder.ClearProviders(); + builder.AddProvider(new XUnitLoggerProvider(_output, LogLevel.Debug)); + }) + .ConfigureServices(services => + { + services.AddAkka("MySys", (builder, provider) => + { + builder.AddStartup((_, _) => throw new TestException("BOOM")); + }); + }) + .Build(); + + await Awaiting(async () => await host.StartAsync()).Should() + .ThrowExactlyAsync().WithMessage("BOOM"); + } + + private class TestException: Exception + { + public TestException(string? message) : base(message) + { + } + } +} \ No newline at end of file diff --git a/src/Akka.Hosting/AkkaHostedService.cs b/src/Akka.Hosting/AkkaHostedService.cs index 65f9df7..14c5c82 100644 --- a/src/Akka.Hosting/AkkaHostedService.cs +++ b/src/Akka.Hosting/AkkaHostedService.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; using Akka.Actor; @@ -72,7 +73,15 @@ async Task TerminationHook() catch (Exception ex) { Logger.Log(LogLevel.Critical, ex, "Unable to start AkkaHostedService - shutting down application"); - HostApplicationLifetime?.StopApplication(); + + // resolve https://github.com/akkadotnet/Akka.Hosting/issues/470 - never allow failures to be silent + Console.WriteLine($"Unable to start AkkaHostedService - shutting down application.\nCause: {ex}"); + + // Best effort to perform a clean stop + var capturedException = ExceptionDispatchInfo.Capture(ex); + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)); + await StopAsync(cts.Token); + capturedException.Throw(); } }