runtime: StopTheHostException should be made public to be dealt with gracefully
Description
In brief, StopTheHostException should be made public as it may need to be handled by framework users.
This commit introduced StopTheHostException thrown out of, ultimately, HostBuilder.Build() on, among other things, adding a migration to a EF/.NET Core 6.0 RC2 project.
The exception itself seems to be expected, and is supposed to be caught by HostFactoryResolver.
However, that private, formally undocumented exception reaches my code which I believe is quite a common pattern:
try
{
CreateHostBuilder().Build().Run()
}
catch (Exception ex)
{
_logger.Fatal(ex, "Unhandled exception");
return 1;
}
The following output is produced on an attempt to add a migration:
PM> Add-Migration InitialCreate -Context PersistedGrantDbContext -OutputDir Migrations\PersistedGrantDbContext Build started… Build succeeded. 18:21:59 [FTL] Unhandled exception Microsoft.Extensions.Hosting.HostFactoryResolver+HostingListener+StopTheHostException: Exception of type ‘Microsoft.Extensions.Hosting.HostFactoryResolver+HostingListener+StopTheHostException’ was thrown. at Microsoft.Extensions.Hosting.HostFactoryResolver.HostingListener.OnNext(KeyValuePair`2 value) at System.Diagnostics.DiagnosticListener.Write(String name, Object value) at Microsoft.Extensions.Hosting.HostBuilder.Build() <snip> To undo this action, use Remove-Migration. PM>
Reproduction Steps
(1) Add try/catch similar to the above around IHostBulder.Build() in any .NET/EF Core 6.0 RC2 project,
(2) Attempt to add a migration.
Expected behavior
StopTheHostException needs to be public and documented, to be able to be gracefully re-thrown. Alternatively, it should never propagate out of the framework.
Actual behavior
StopTheHostException is private, undocumented, and reaches customer code.
Regression?
Yes - introduced in .NET Core 6.
Known Workarounds
I fixed the issue with the following:
catch (Exception ex)
{
string type = ex.GetType().Name;
if (type.Equals("StopTheHostException", StringComparison.Ordinal))
{
throw;
}
_logger.Fatal(ex, "Unhandled exception");
return 1;
}
Normally, I would use catch(StopTheHostException) or similar but I can’t because StopTheHostException is private.
Configuration
Any ASP.NET Core/EF project, and potentially other kinds of projects.
Other information
No response
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 26
- Comments: 19 (15 by maintainers)
Video
We renamed
StopTheHostExceptiontoHostAbortedExceptionnow that it’s a public type. (And sealed it, and added [Serializable] for .NET Framework interop concerns)OK lets expose the exception. I’m sympathetic to the problems experienced here as well.
If that’s being done for other Exception-derived types, then yes. If not, then no 😄. (I don’t know off the top of my head, but that’s the formula)
@maryamariyan Thank you for waiting. I’ve been busy lately. The PR will be made this week.
When do you see this exception happen in practice? Locally during development right when adding Migrations right? Narrow doesn’t mean that its not important, but if there are more cases than we’re aware of, that would be nice to know.
Any idea on what the proper way to handle this would be?
my code is now:
I’m running into this ex with a custom bootstrapper and ef core - would this be the proper way to handle this?