Skip to content

StopTheHostException should be made public to be dealt with gracefully #60600

@cristalink

Description

@cristalink

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()

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

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-Extensions-Hostinghelp wanted[up-for-grabs] Good issue for external contributors

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions