Skip to content

Commit

Permalink
Show relevant error for invalid command line args.
Browse files Browse the repository at this point in the history
Also fixes the unreported but apparently broken error display for other errors, like invalid games. The originally-caught exceptions were nested in an Autofac exception and have to be unwrapped to restore the original behavior.

Fixes #127
  • Loading branch information
focustense committed Oct 3, 2021
1 parent e828e4c commit 1be5b32
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 16 deletions.
57 changes: 41 additions & 16 deletions Focus.Apps.EasyNpc/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
using Autofac;
using Autofac.Core;
using CommandLine;
using CommandLine.Text;
using Focus.Apps.EasyNpc.Configuration;
using Focus.Apps.EasyNpc.Main;
using Focus.Apps.EasyNpc.Reports;
using Focus.ModManagers;
using Serilog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;

namespace Focus.Apps.EasyNpc
Expand All @@ -16,11 +20,21 @@ namespace Focus.Apps.EasyNpc
/// </summary>
public partial class App : Application
{
private IDisposable? container;

private void Application_Startup(object sender, StartupEventArgs e)
{
Console.WriteLine("Application started");
Parser.Default.ParseArguments<CommandLineOptions>(e.Args)
.WithParsed(Start);
.WithParsed(Start)
.WithNotParsed(DisplayErrors);
}

private void DisplayErrors(IEnumerable<Error> errors)
{
var sentenceBuilder = SentenceBuilder.Create();
var errorMessages = errors.Select(e => sentenceBuilder.FormatError(e));
Warn(StartupWarnings.InvalidCommandLine(errorMessages), true);
}

private void Start(CommandLineOptions options)
Expand All @@ -36,46 +50,51 @@ private void Start(CommandLineOptions options)
if (isVortex && string.IsNullOrEmpty(options.VortexManifest) &&
!Warn(StartupWarnings.MissingVortexManifest))
{
Current.Shutdown();
return;
}

var container = AppContainer.Build(options, startupInfo);
this.container = container;
var logger = container.Resolve<ILogger>();
var mainWindow = MainWindow = new MainWindow(logger, container);
if (isFirstLaunch && string.IsNullOrEmpty(Settings.Default.DefaultModRootDirectory))
Settings.Default.DefaultModRootDirectory = container.Resolve<IModManagerConfiguration>().ModsDirectory;
try
{
if (options.PostBuild)
try
{
var postBuildReportViewModel = container.Resolve<PostBuildReportViewModel>();
mainWindow.DataContext = postBuildReportViewModel;
_ = postBuildReportViewModel.UpdateReport();
if (options.PostBuild)
{
var postBuildReportViewModel = container.Resolve<PostBuildReportViewModel>();
mainWindow.DataContext = postBuildReportViewModel;
_ = postBuildReportViewModel.UpdateReport();
}
else
{
var mainViewModelFactory = container.Resolve<MainViewModel.Factory>();
var mainViewModel = mainViewModelFactory(isFirstLaunch);
mainWindow.DataContext = mainViewModel;
}
}
else
catch (DependencyResolutionException ex)
{
var mainViewModelFactory = container.Resolve<MainViewModel.Factory>();
var mainViewModel = mainViewModelFactory(isFirstLaunch);
mainWindow.DataContext = mainViewModel;
if (ex.InnerException is not null)
throw ex.InnerException;
throw;
}
mainWindow.Show();
}
catch (MissingGameDataException ex)
{
Warn(StartupWarnings.MissingGameData(ex.GameId, ex.GameName), true);
container.Dispose();
Current.Shutdown();
}
catch (UnsupportedGameException ex)
{
Warn(StartupWarnings.UnsupportedGame(ex.GameId, ex.GameName), true);
container.Dispose();
Current.Shutdown();
}
}

private static bool Warn(StartupWarning warning, bool isFatal = false)
private bool Warn(StartupWarning warning, bool isFatal = false)
{
var model = new StartupWarningViewModel
{
Expand All @@ -87,7 +106,13 @@ private static bool Warn(StartupWarning warning, bool isFatal = false)
{
DataContext = model
};
return warningWindow.ShowDialog() == true;
var ignored = warningWindow.ShowDialog() == true;
if (!ignored)
{
container?.Dispose();
Current.Shutdown();
}
return ignored;
}
}
}
19 changes: 19 additions & 0 deletions Focus.Apps.EasyNpc/Main/StartupWarningWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,25 @@
</ControlTemplate>
<Style x:Key="ListItemStyle" TargetType="TextBlock" BasedOn="{StaticResource ParagraphStyle}"/>

<DataTemplate DataType="{x:Type main:InvalidCommandLineContent}">
<ui:SimpleStackPanel>
<TextBlock Style="{StaticResource ParagraphStyle}">
<Run Text="{StaticResource AppName}"/> was started with invalid command-line arguments and cannot continue. The errors are listed below.
</TextBlock>
<ItemsControl ItemsSource="{Binding ErrorMessages}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Template="{StaticResource ListItem}" Tag="">
<TextBlock Style="{StaticResource FirstParagraphStyle}" Text="{Binding}"/>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock Style="{StaticResource ParagraphStyle}">
Please correct these settings in your mod manager and restart the app.
</TextBlock>
</ui:SimpleStackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type main:MissingVortexManifestContent}">
<ui:SimpleStackPanel>
<TextBlock Style="{StaticResource ParagraphStyle}">
Expand Down
13 changes: 13 additions & 0 deletions Focus.Apps.EasyNpc/Main/StartupWarnings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Focus.Apps.EasyNpc.Main
{
Expand All @@ -16,6 +18,12 @@ public class StartupWarnings
Description = new MissingVortexManifestContent(),
};

public static StartupWarning InvalidCommandLine(IEnumerable<string> errorMessages) => new()
{
Title = "Invalid options",
Description = new InvalidCommandLineContent { ErrorMessages = errorMessages },
};

public static StartupWarning MissingGameData(string gameId, string gameName) => new()
{
Title = "Game not found",
Expand All @@ -29,6 +37,11 @@ public class StartupWarnings
};
}

public class InvalidCommandLineContent
{
public IEnumerable<string> ErrorMessages { get; init; } = Enumerable.Empty<string>();
}

public class MissingVortexManifestContent
{
public string ExtensionUrl { get; private init; } = "https://www.nexusmods.com/site/mods/265";
Expand Down

0 comments on commit 1be5b32

Please sign in to comment.