mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Merge pull request #236 from Noggog/Exceptions-As-Data-Thoughts
Exceptions as data thoughts
This commit is contained in:
commit
553ea3c701
@ -48,12 +48,11 @@ namespace Wabbajack.Common
|
||||
else if (source.EndsWith(".exe"))
|
||||
ExtractAllWithInno(source, dest);
|
||||
else
|
||||
ExtractAllWith7Zip(queue, source, dest);
|
||||
ExtractAllWith7Zip(source, dest);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
queue.Log($"Error while extracting {source}");
|
||||
throw ex;
|
||||
Utils.ErrorThrow(ex, $"Error while extracting {source}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +82,7 @@ namespace Wabbajack.Common
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.LogToFile($"Error while setting process priority level for innounp.exe\n{e}");
|
||||
Utils.Error(e, "Error while setting process priority level for innounp.exe");
|
||||
}
|
||||
|
||||
var name = Path.GetFileName(source);
|
||||
@ -104,7 +103,7 @@ namespace Wabbajack.Common
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.LogToFile($"Error while reading StandardOutput for innounp.exe\n{e}");
|
||||
Utils.Error(e, "Error while reading StandardOutput for innounp.exe");
|
||||
}
|
||||
|
||||
p.WaitForExit();
|
||||
@ -154,14 +153,13 @@ namespace Wabbajack.Common
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
queue.Log($"While Extracting {source}");
|
||||
throw ex;
|
||||
Utils.ErrorThrow(ex, $"While Extracting {source}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExtractAllWith7Zip(WorkQueue queue, string source, string dest)
|
||||
private static void ExtractAllWith7Zip(string source, string dest)
|
||||
{
|
||||
queue.Log(new GenericInfo($"Extracting {Path.GetFileName(source)}", $"The contents of {source} are being extracted to {dest} using 7zip.exe"));
|
||||
Utils.Log(new GenericInfo($"Extracting {Path.GetFileName(source)}", $"The contents of {source} are being extracted to {dest} using 7zip.exe"));
|
||||
|
||||
var info = new ProcessStartInfo
|
||||
{
|
||||
@ -210,7 +208,7 @@ namespace Wabbajack.Common
|
||||
{
|
||||
return;
|
||||
}
|
||||
queue.Log(new _7zipReturnError(p.ExitCode, source, dest, p.StandardOutput.ReadToEnd()));
|
||||
Utils.Log(new _7zipReturnError(p.ExitCode, source, dest, p.StandardOutput.ReadToEnd()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -6,10 +6,11 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Wabbajack.Common.StatusFeed
|
||||
{
|
||||
public abstract class AErrorMessage : Exception, IError
|
||||
public abstract class AErrorMessage : Exception, IException
|
||||
{
|
||||
public DateTime Timestamp { get; } = DateTime.Now;
|
||||
public abstract string ShortDescription { get; }
|
||||
public abstract string ExtendedDescription { get; }
|
||||
Exception IException.Exception => this;
|
||||
}
|
||||
}
|
||||
|
@ -8,25 +8,25 @@ namespace Wabbajack.Common.StatusFeed.Errors
|
||||
{
|
||||
public class _7zipReturnError : AStatusMessage, IError
|
||||
{
|
||||
private string _destination;
|
||||
private string _filename;
|
||||
private int _code;
|
||||
private string _7zip_output;
|
||||
public string Destination { get; }
|
||||
public string Filename;
|
||||
public int Code;
|
||||
public string _7zip_output;
|
||||
public override string ShortDescription => $"7Zip returned an error while executing";
|
||||
|
||||
public override string ExtendedDescription =>
|
||||
$@"7Zip.exe should always return 0 when it finishes executing. While extracting {_filename} 7Zip encountered some error and
|
||||
instead returned {_code} which indicates there was an error. The archive might be corrupt or in a format that 7Zip cannot handle. Please verify the file is valid and that you
|
||||
haven't run out of disk space in the {_destination} folder.
|
||||
$@"7Zip.exe should always return 0 when it finishes executing. While extracting {Filename} 7Zip encountered some error and
|
||||
instead returned {Code} which indicates there was an error. The archive might be corrupt or in a format that 7Zip cannot handle. Please verify the file is valid and that you
|
||||
haven't run out of disk space in the {Destination} folder.
|
||||
|
||||
7Zip Output:
|
||||
{_7zip_output}";
|
||||
|
||||
public _7zipReturnError(int code, string filename, string destination, string output)
|
||||
{
|
||||
_code = code;
|
||||
_filename = filename;
|
||||
_destination = destination;
|
||||
Code = code;
|
||||
Filename = filename;
|
||||
Destination = destination;
|
||||
_7zip_output = output;
|
||||
}
|
||||
}
|
||||
|
27
Wabbajack.Common/StatusFeed/Errors/GenericException.cs
Normal file
27
Wabbajack.Common/StatusFeed/Errors/GenericException.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Wabbajack.Common.StatusFeed.Errors
|
||||
{
|
||||
public class GenericException : IException
|
||||
{
|
||||
public string ExtraMessage { get; }
|
||||
|
||||
public DateTime Timestamp { get; } = DateTime.Now;
|
||||
|
||||
public string ShortDescription => ExtraMessage ?? Exception?.Message;
|
||||
|
||||
public string ExtendedDescription => $"{ExtraMessage}: {Exception?.ToString()}";
|
||||
|
||||
public Exception Exception { get; }
|
||||
|
||||
public GenericException(Exception exception, string extraMessage = null)
|
||||
{
|
||||
ExtraMessage = extraMessage;
|
||||
Exception = exception;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ namespace Wabbajack.Common.StatusFeed.Errors
|
||||
_msg = msg;
|
||||
}
|
||||
|
||||
public override string ShortDescription { get => _msg; }
|
||||
public override string ExtendedDescription { get; } = "";
|
||||
public override string ShortDescription => _msg;
|
||||
public override string ExtendedDescription => _msg;
|
||||
}
|
||||
}
|
||||
|
13
Wabbajack.Common/StatusFeed/IException.cs
Normal file
13
Wabbajack.Common/StatusFeed/IException.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Wabbajack.Common.StatusFeed
|
||||
{
|
||||
public interface IException : IError
|
||||
{
|
||||
Exception Exception { get; }
|
||||
}
|
||||
}
|
@ -6,24 +6,6 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Wabbajack.Common.StatusFeed
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a message that requires user interaction. The user must perform some action
|
||||
/// or make a choice.
|
||||
/// </summary>
|
||||
public interface IUserIntervention<T> : IStatusMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// The user didn't make a choice, so this action should be aborted
|
||||
/// </summary>
|
||||
void Cancel();
|
||||
|
||||
/// <summary>
|
||||
/// The user has provided the required information.
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
void Resume(T result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a message that requires user interaction. The user must perform some action
|
||||
/// or make a choice.
|
||||
@ -34,10 +16,5 @@ namespace Wabbajack.Common.StatusFeed
|
||||
/// The user didn't make a choice, so this action should be aborted
|
||||
/// </summary>
|
||||
void Cancel();
|
||||
|
||||
/// <summary>
|
||||
/// Resume without any further information
|
||||
/// </summary>
|
||||
void Resume();
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ using IniParser;
|
||||
using Newtonsoft.Json;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.Common.StatusFeed;
|
||||
using Wabbajack.Common.StatusFeed.Errors;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
using Directory = System.IO.Directory;
|
||||
@ -63,31 +64,39 @@ namespace Wabbajack.Common
|
||||
|
||||
public static T Log<T>(T msg) where T : IStatusMessage
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
File.AppendAllText(LogFile, msg + "\r\n");
|
||||
}
|
||||
LogToFile(msg.ShortDescription);
|
||||
LoggerSubj.OnNext(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
public static void Error(AErrorMessage err)
|
||||
public static void Error(Exception ex, string extraMessage = null)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
File.AppendAllText(LogFile, err.ShortDescription + "\r\n");
|
||||
Log(new GenericException(ex, extraMessage));
|
||||
}
|
||||
|
||||
public static void ErrorThrow(Exception ex, string extraMessage = null)
|
||||
{
|
||||
Error(ex, extraMessage);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
public static void Error(IException err)
|
||||
{
|
||||
LogToFile($"{err.ShortDescription}\n{err.Exception.StackTrace}");
|
||||
LoggerSubj.OnNext(err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
public static void LogToFile(string msg)
|
||||
public static void ErrorThrow(IException err)
|
||||
{
|
||||
Error(err);
|
||||
throw err.Exception;
|
||||
}
|
||||
|
||||
private static void LogToFile(string msg)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
msg = $"{(DateTime.Now - _startTime).TotalSeconds:0.##} - {msg}";
|
||||
|
||||
File.AppendAllText(LogFile, msg + "\r\n");
|
||||
File.AppendAllText(LogFile, $"{(DateTime.Now - _startTime).TotalSeconds:0.##} - {msg}\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -593,11 +602,6 @@ namespace Wabbajack.Common
|
||||
return stream.Result;
|
||||
}
|
||||
|
||||
public static string ExceptionToString(this Exception ex)
|
||||
{
|
||||
return ex.ToString();
|
||||
}
|
||||
|
||||
public static IEnumerable<T> DistinctBy<T, V>(this IEnumerable<T> vs, Func<T, V> select)
|
||||
{
|
||||
var set = new HashSet<V>();
|
||||
|
@ -112,9 +112,11 @@
|
||||
<Compile Include="StatusFeed\AStatusMessage.cs" />
|
||||
<Compile Include="StatusFeed\Errors\7zipReturnError.cs" />
|
||||
<Compile Include="StatusFeed\Errors\FileExtractionError.cs" />
|
||||
<Compile Include="StatusFeed\Errors\GenericException.cs" />
|
||||
<Compile Include="StatusFeed\Errors\UnconvertedError.cs" />
|
||||
<Compile Include="StatusFeed\GenericInfo.cs" />
|
||||
<Compile Include="StatusFeed\IError.cs" />
|
||||
<Compile Include="StatusFeed\IException.cs" />
|
||||
<Compile Include="StatusFeed\IInfo.cs" />
|
||||
<Compile Include="StatusFeed\IStatusMessage.cs" />
|
||||
<Compile Include="StatusFeed\IUserIntervention.cs" />
|
||||
|
@ -22,9 +22,6 @@ namespace Wabbajack.Common
|
||||
private readonly Subject<CPUStatus> _Status = new Subject<CPUStatus>();
|
||||
public IObservable<CPUStatus> Status => _Status;
|
||||
|
||||
private static readonly Subject<IStatusMessage> _messages = new Subject<IStatusMessage>();
|
||||
public IObservable<IStatusMessage> Messages => _messages;
|
||||
|
||||
public static List<Thread> Threads { get; private set; }
|
||||
|
||||
public WorkQueue(int threadCount = 0)
|
||||
@ -32,16 +29,6 @@ namespace Wabbajack.Common
|
||||
StartThreads(threadCount == 0 ? Environment.ProcessorCount : threadCount);
|
||||
}
|
||||
|
||||
public void Log(IStatusMessage msg)
|
||||
{
|
||||
_messages.OnNext(msg);
|
||||
}
|
||||
|
||||
public void Log(string msg)
|
||||
{
|
||||
_messages.OnNext(new GenericInfo(msg));
|
||||
}
|
||||
|
||||
private void StartThreads(int threadCount)
|
||||
{
|
||||
ThreadCount = threadCount;
|
||||
|
@ -10,29 +10,29 @@ namespace Wabbajack.Lib.CompilationSteps.CompilationErrors
|
||||
{
|
||||
public class InvalidGameESMError : AErrorMessage
|
||||
{
|
||||
private readonly string _hash;
|
||||
private readonly string _path;
|
||||
public string Hash { get; }
|
||||
public string PathToFile { get; }
|
||||
private readonly CleanedESM _esm;
|
||||
private string _gameFileName => Path.GetFileName(_esm.To);
|
||||
public string GameFileName => Path.GetFileName(_esm.To);
|
||||
public override string ShortDescription
|
||||
{
|
||||
get =>
|
||||
$"Game file {_gameFileName} has a hash of {_hash} which does not match the expected value of {_esm.SourceESMHash}";
|
||||
$"Game file {GameFileName} has a hash of {Hash} which does not match the expected value of {_esm.SourceESMHash}";
|
||||
}
|
||||
|
||||
public override string ExtendedDescription
|
||||
{
|
||||
get =>
|
||||
$@"This modlist is setup to perform automatic cleaning of the stock game file {_gameFileName} in order to perform this cleaning Wabbajack must first verify that the
|
||||
source file is in the correct state. It seems that the file in your game directory has a hash of {_hash} instead of the expect hash of {_esm.SourceESMHash}. This could be caused by
|
||||
$@"This modlist is setup to perform automatic cleaning of the stock game file {GameFileName} in order to perform this cleaning Wabbajack must first verify that the
|
||||
source file is in the correct state. It seems that the file in your game directory has a hash of {Hash} instead of the expect hash of {_esm.SourceESMHash}. This could be caused by
|
||||
the modlist expecting a different of the game than you currently have installed, or perhaps you have already cleaned the file. You could attempt to fix this error by re-installing
|
||||
the game, and then attempting to re-install this modlist. Also verify that the version of the game you have installed matches the version expected by this modlist.";
|
||||
}
|
||||
|
||||
public InvalidGameESMError(CleanedESM esm, string hash, string path)
|
||||
{
|
||||
_hash = hash;
|
||||
_path = path;
|
||||
Hash = hash;
|
||||
PathToFile = path;
|
||||
_esm = esm;
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ namespace Wabbajack.Lib.CompilationSteps
|
||||
foreach (var match in matches)
|
||||
{
|
||||
if (match is IgnoredDirectly)
|
||||
Utils.Error(new UnconvertedError($"File required for BSA {source.Path} creation doesn't exist: {match.To}"));
|
||||
Utils.ErrorThrow(new UnconvertedError($"File required for BSA {source.Path} creation doesn't exist: {match.To}"));
|
||||
_mo2Compiler.ExtraFiles.Add(match);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ namespace Wabbajack.Lib.CompilationSteps
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.LogToFile($"Exception while trying to evolve source to FromSteam\n{e}");
|
||||
Utils.Error(e, $"Exception while trying to evolve source to FromSteam");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
|
||||
if (stream.IsFaulted || response.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
Utils.Log($"While downloading {Url} - {stream.Exception.ExceptionToString()}");
|
||||
Utils.Error(stream.Exception, $"While downloading {Url}");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -46,12 +46,12 @@ namespace Wabbajack.Lib.Downloaders
|
||||
var status = client.GetUserStatus();
|
||||
if (!client.IsAuthenticated)
|
||||
{
|
||||
Utils.Error(new UnconvertedError($"Authenticating for the Nexus failed. A nexus account is required to automatically download mods."));
|
||||
Utils.ErrorThrow(new UnconvertedError($"Authenticating for the Nexus failed. A nexus account is required to automatically download mods."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (status.is_premium) return;
|
||||
Utils.Error(new UnconvertedError($"Automated installs with Wabbajack requires a premium nexus account. {client.Username} is not a premium account."));
|
||||
Utils.ErrorThrow(new UnconvertedError($"Automated installs with Wabbajack requires a premium nexus account. {client.Username} is not a premium account."));
|
||||
}
|
||||
|
||||
public class State : AbstractDownloadState
|
||||
|
@ -140,7 +140,7 @@ namespace Wabbajack.Lib
|
||||
var hash = gameFile.FileHash();
|
||||
if (hash != esm.SourceESMHash)
|
||||
{
|
||||
Utils.Error(new InvalidGameESMError(esm, hash, gameFile));
|
||||
Utils.ErrorThrow(new InvalidGameESMError(esm, hash, gameFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ will be reverted. Are you sure you wish to continue?";
|
||||
_source.SetResult(Choice.Abort);
|
||||
}
|
||||
|
||||
public void Resume()
|
||||
public void Confirm()
|
||||
{
|
||||
_source.SetResult(Choice.Continue);
|
||||
}
|
||||
|
@ -238,9 +238,7 @@ namespace Wabbajack.Lib
|
||||
}
|
||||
catch (JsonSerializationException e)
|
||||
{
|
||||
Info("Failed to parse vortex.deployment.json!");
|
||||
Utils.LogToFile(e.Message);
|
||||
Utils.LogToFile(e.StackTrace);
|
||||
Utils.Error(e, "Failed to parse vortex.deployment.json!");
|
||||
}
|
||||
|
||||
VortexDeployment.files.Do(f =>
|
||||
@ -352,7 +350,7 @@ namespace Wabbajack.Lib
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.LogToFile($"Exception while writing to disk at {filePath}\n{e}");
|
||||
Utils.Error(e, $"Exception while writing to disk at {filePath}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ namespace Wabbajack
|
||||
catch (Exception ex)
|
||||
{
|
||||
while (ex.InnerException != null) ex = ex.InnerException;
|
||||
Utils.Log($"Compiler error: {ex.ExceptionToString()}");
|
||||
Utils.Error(ex, $"Compiler error");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ namespace Wabbajack
|
||||
catch (Exception ex)
|
||||
{
|
||||
while (ex.InnerException != null) ex = ex.InnerException;
|
||||
Utils.Log($"Compiler error: {ex.ExceptionToString()}");
|
||||
Utils.Error(ex, $"Compiler error");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ namespace Wabbajack
|
||||
catch (Exception ex)
|
||||
{
|
||||
while (ex.InnerException != null) ex = ex.InnerException;
|
||||
Utils.Log($"Compiler error: {ex.ExceptionToString()}");
|
||||
Utils.Error(ex, $"Compiler error");
|
||||
return;
|
||||
}
|
||||
await Task.Run(async () =>
|
||||
@ -115,7 +115,7 @@ namespace Wabbajack
|
||||
catch (Exception ex)
|
||||
{
|
||||
while (ex.InnerException != null) ex = ex.InnerException;
|
||||
Utils.Log($"Compiler error: {ex.ExceptionToString()}");
|
||||
Utils.Error(ex, $"Compiler error");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ namespace Wabbajack
|
||||
{
|
||||
var result = MessageBox.Show(msg.ExtendedDescription, msg.ShortDescription, MessageBoxButton.OKCancel);
|
||||
if (result == MessageBoxResult.OK)
|
||||
msg.Resume();
|
||||
msg.Confirm();
|
||||
else
|
||||
msg.Cancel();
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ namespace Wabbajack
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Utils.LogToFile($"Exception while caching Mod List image {Name}\n{ex.ExceptionToString()}");
|
||||
Utils.Error(ex, $"Exception while caching Mod List image {Name}");
|
||||
return default(MemoryStream);
|
||||
}
|
||||
})
|
||||
@ -80,7 +80,7 @@ namespace Wabbajack
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Utils.LogToFile($"Exception while caching Mod List image {Name}\n{ex.ExceptionToString()}");
|
||||
Utils.Error(ex, $"Exception while caching Mod List image {Name}");
|
||||
return default(BitmapImage);
|
||||
}
|
||||
})
|
||||
|
@ -59,7 +59,7 @@ namespace Wabbajack
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Utils.LogToFile($"Exception while caching slide {ModName} ({ModID})\n{ex.ExceptionToString()}");
|
||||
Utils.Error(ex, $"Exception while caching slide {ModName} ({ModID})");
|
||||
return default(MemoryStream);
|
||||
}
|
||||
})
|
||||
@ -79,7 +79,7 @@ namespace Wabbajack
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Utils.LogToFile($"Exception while caching slide {ModName} ({ModID})\n{ex.ExceptionToString()}");
|
||||
Utils.Error(ex, $"Exception while caching slide {ModName} ({ModID})");
|
||||
return default(BitmapImage);
|
||||
}
|
||||
finally
|
||||
|
@ -23,8 +23,7 @@ namespace Wabbajack
|
||||
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
|
||||
{
|
||||
// Don't do any special logging side effects
|
||||
Wabbajack.Common.Utils.Log("Uncaught error:");
|
||||
Wabbajack.Common.Utils.Log(((Exception)e.ExceptionObject).ExceptionToString());
|
||||
Wabbajack.Common.Utils.Error(((Exception)e.ExceptionObject), "Uncaught error");
|
||||
};
|
||||
|
||||
var appPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
||||
|
Loading…
Reference in New Issue
Block a user