Add nice error page for boot, like in v8
This commit is contained in:
@@ -19,6 +19,12 @@ namespace Umbraco.Cms.Core.Configuration.Models
|
||||
/// </remarks>
|
||||
public bool InstallUnattended { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether unattended upgrades are enabled.
|
||||
/// </summary>
|
||||
public bool UpgradeUnattended { get; set; } = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value to use for creating a user with a name for Unattended Installs
|
||||
/// </summary>
|
||||
|
||||
@@ -14,7 +14,6 @@ using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Migrations.Install;
|
||||
using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Runtime
|
||||
{
|
||||
@@ -96,7 +95,7 @@ namespace Umbraco.Cms.Infrastructure.Runtime
|
||||
|
||||
if (State.Level <= RuntimeLevel.BootFailed)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot start the runtime if the runtime level is less than or equal to {RuntimeLevel.BootFailed}");
|
||||
return; // The exception will be rethrown by BootFailedMiddelware
|
||||
}
|
||||
|
||||
IApplicationShutdownRegistry hostingEnvironmentLifetime = _applicationShutdownRegistry;
|
||||
@@ -110,8 +109,8 @@ namespace Umbraco.Cms.Infrastructure.Runtime
|
||||
|
||||
await _eventAggregator.PublishAsync(new UmbracoApplicationStarting(State.Level), cancellationToken);
|
||||
|
||||
// if level is Updrade and reason is UpgradeMigrations, that means we need to perform an unattended upgrade
|
||||
if (State.Reason == RuntimeLevelReason.UpgradeMigrations && State.Level == RuntimeLevel.Upgrade)
|
||||
// if level is Run and reason is UpgradeMigrations, that means we need to perform an unattended upgrade
|
||||
if (State.Reason == RuntimeLevelReason.UpgradeMigrations && State.Level == RuntimeLevel.Run)
|
||||
{
|
||||
// do the upgrade
|
||||
DoUnattendedUpgrade();
|
||||
@@ -181,11 +180,12 @@ namespace Umbraco.Cms.Infrastructure.Runtime
|
||||
_databaseFactory.ConfigureForUpgrade();
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
State.Configure(RuntimeLevel.BootFailed, RuntimeLevelReason.BootFailedOnException);
|
||||
timer?.Fail();
|
||||
throw;
|
||||
_logger.LogError(ex, "Boot Failed");
|
||||
// We do not throw the exception. It will be rethrown by BootFailedMiddleware
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,8 @@ namespace Umbraco.Cms.Core
|
||||
|
||||
// else it is bad enough that we want to throw
|
||||
Reason = RuntimeLevelReason.BootFailedCannotConnectToDatabase;
|
||||
throw new BootFailedException("A connection string is configured but Umbraco could not connect to the database.");
|
||||
BootFailedException =new BootFailedException("A connection string is configured but Umbraco could not connect to the database.");
|
||||
throw BootFailedException;
|
||||
}
|
||||
case UmbracoDatabaseState.NotInstalled:
|
||||
{
|
||||
@@ -133,7 +134,7 @@ namespace Umbraco.Cms.Core
|
||||
// although the files version matches the code version, the database version does not
|
||||
// which means the local files have been upgraded but not the database - need to upgrade
|
||||
_logger.LogDebug("Has not reached the final upgrade step, need to upgrade Umbraco.");
|
||||
Level = RuntimeLevel.Upgrade;
|
||||
Level = _unattendedSettings.Value.UpgradeUnattended ? RuntimeLevel.Run : RuntimeLevel.Upgrade;
|
||||
Reason = RuntimeLevelReason.UpgradeMigrations;
|
||||
}
|
||||
break;
|
||||
@@ -192,7 +193,8 @@ namespace Umbraco.Cms.Core
|
||||
|
||||
// else it is bad enough that we want to throw
|
||||
Reason = RuntimeLevelReason.BootFailedCannotCheckUpgradeState;
|
||||
throw new BootFailedException("Could not check the upgrade state.", e);
|
||||
BootFailedException = new BootFailedException("Could not check the upgrade state.", e);
|
||||
throw BootFailedException;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,9 +253,12 @@ namespace Umbraco.Cms.Core
|
||||
_logger.LogInformation(ex, "Error during unattended install.");
|
||||
database.AbortTransaction();
|
||||
|
||||
throw new UnattendedInstallException(
|
||||
var innerException = new UnattendedInstallException(
|
||||
"The database configuration failed with the following message: " + ex.Message
|
||||
+ "\n Please check log file for additional information (can be found in '/App_Data/Logs/')");
|
||||
BootFailedException = new BootFailedException(innerException.Message, innerException);
|
||||
|
||||
throw BootFailedException;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ namespace Umbraco.Extensions
|
||||
|
||||
if (!app.UmbracoCanBoot())
|
||||
{
|
||||
app.UseStaticFiles(); // We need static files to show the nice error page.
|
||||
app.UseMiddleware<BootFailedMiddleware>();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Exceptions;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.Middleware
|
||||
@@ -12,10 +15,12 @@ namespace Umbraco.Cms.Web.Common.Middleware
|
||||
public class BootFailedMiddleware : IMiddleware
|
||||
{
|
||||
private readonly IRuntimeState _runtimeState;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
|
||||
public BootFailedMiddleware(IRuntimeState runtimeState)
|
||||
public BootFailedMiddleware(IRuntimeState runtimeState, IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
_runtimeState = runtimeState;
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
||||
@@ -23,12 +28,35 @@ namespace Umbraco.Cms.Web.Common.Middleware
|
||||
if (_runtimeState.Level == RuntimeLevel.BootFailed)
|
||||
{
|
||||
// short circuit
|
||||
BootFailedException.Rethrow(_runtimeState.BootFailedException);
|
||||
//
|
||||
|
||||
if (_hostingEnvironment.IsDebugMode)
|
||||
{
|
||||
BootFailedException.Rethrow(_runtimeState.BootFailedException);
|
||||
}
|
||||
else // Print a nice error page
|
||||
{
|
||||
context.Response.Clear();
|
||||
context.Response.StatusCode = 500;
|
||||
|
||||
var file = GetBootErrorFileName();
|
||||
|
||||
var viewContent = await File.ReadAllTextAsync(file);
|
||||
await context.Response.WriteAsync(viewContent, Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await next(context);
|
||||
}
|
||||
|
||||
}
|
||||
private string GetBootErrorFileName()
|
||||
{
|
||||
var fileName = _hostingEnvironment.MapPathWebRoot("~/config/errors/BootFailed.html");
|
||||
if (File.Exists(fileName)) return fileName;
|
||||
|
||||
return _hostingEnvironment.MapPathWebRoot("~/umbraco/views/errors/BootFailed.html");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user