diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index d9ca14136..2939d3378 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -20,6 +20,7 @@ using Jellyfin.Drawing.Skia; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Extensions; +using MediaBrowser.WebDashboard.Api; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -185,8 +186,23 @@ namespace Jellyfin.Server new ManagedFileSystem(_loggerFactory.CreateLogger(), appPaths), GetImageEncoder(appPaths), new NetworkManager(_loggerFactory.CreateLogger())); + try { + // If hosting the web client, validate the client content path + if (startupConfig.HostWebClient()) + { + string webContentPath = DashboardService.GetDashboardUIPath(startupConfig, appHost.ServerConfigurationManager); + if (!Directory.Exists(webContentPath) || Directory.GetFiles(webContentPath).Length == 0) + { + throw new InvalidOperationException( + "The server is expected to host the web client, but the provided content directory is either " + + $"invalid or empty: {webContentPath}. If you do not want to host the web client with the " + + "server, you may set the '--nowebclient' command line flag, or set" + + $"'{MediaBrowser.Controller.Extensions.ConfigurationExtensions.HostWebClientKey}=false' in your config settings."); + } + } + ServiceCollection serviceCollection = new ServiceCollection(); await appHost.InitAsync(serviceCollection, startupConfig).ConfigureAwait(false); diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 1ca035f7b..938ab513b 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -161,22 +161,27 @@ namespace MediaBrowser.WebDashboard.Api /// Gets the path of the directory containing the static web interface content, or null if the server is not /// hosting the web client. /// - public string DashboardUIPath + public string DashboardUIPath => GetDashboardUIPath(_appConfig, _serverConfigurationManager); + + /// + /// Gets the path of the directory containing the static web interface content. + /// + /// The app configuration. + /// The server configuration manager. + /// The directory path, or null if the server is not hosting the web client. + public static string GetDashboardUIPath(IConfiguration appConfig, IServerConfigurationManager serverConfigManager) { - get + if (!appConfig.HostWebClient()) { - if (!_appConfig.HostWebClient()) - { - return null; - } - - if (!string.IsNullOrEmpty(_serverConfigurationManager.Configuration.DashboardSourcePath)) - { - return _serverConfigurationManager.Configuration.DashboardSourcePath; - } - - return _serverConfigurationManager.ApplicationPaths.WebPath; + return null; } + + if (!string.IsNullOrEmpty(serverConfigManager.Configuration.DashboardSourcePath)) + { + return serverConfigManager.Configuration.DashboardSourcePath; + } + + return serverConfigManager.ApplicationPaths.WebPath; } [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")]