Reimplemented error handling for SettingsFile
This commit is contained in:
@@ -46,59 +46,8 @@ public static class Installer
|
|||||||
public static async Task SetupPluginDatabase()
|
public static async Task SetupPluginDatabase()
|
||||||
{
|
{
|
||||||
Console.WriteLine("The plugin database is required to run the bot but there is nothing configured yet.");
|
Console.WriteLine("The plugin database is required to run the bot but there is nothing configured yet.");
|
||||||
Console.WriteLine("Please select one option : ");
|
Console.WriteLine("Downloading the default database...");
|
||||||
Console.WriteLine("1. Download the official database file");
|
await DownloadPluginDatabase();
|
||||||
Console.WriteLine("2. Create a new (CUSTOM) database file");
|
|
||||||
var choice = 0;
|
|
||||||
Console.Write("Choice : ");
|
|
||||||
choice = int.Parse(Console.ReadLine());
|
|
||||||
if (choice != 1 && choice != 2)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Invalid choice !");
|
|
||||||
Console.WriteLine("Please restart the installer !");
|
|
||||||
Console.ReadKey();
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (choice == 1)
|
|
||||||
await DownloadPluginDatabase();
|
|
||||||
|
|
||||||
if (choice == 2)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Do you have a url to a valid database file ? (y/n)");
|
|
||||||
var answer = Console.ReadLine();
|
|
||||||
if (answer == "y")
|
|
||||||
{
|
|
||||||
Console.WriteLine("Please enter the url :");
|
|
||||||
var url = Console.ReadLine();
|
|
||||||
await DownloadPluginDatabase(url);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine("Do you want to create a new database file ? (y/n)");
|
|
||||||
answer = Console.ReadLine();
|
|
||||||
if (answer == "y")
|
|
||||||
{
|
|
||||||
Console.WriteLine("A new file will be generated at ./Data/Resources/URLs.json");
|
|
||||||
Console.WriteLine("Please edit the file and restart the bot !");
|
|
||||||
Directory.CreateDirectory("./Data/Resources");
|
|
||||||
await File.WriteAllTextAsync("./Data/Resources/URLs.json",
|
|
||||||
@"
|
|
||||||
{
|
|
||||||
""PluginList"": """",
|
|
||||||
""PluginVersions"": """",
|
|
||||||
""StartupMessage"": """",
|
|
||||||
""SetupKeys"": """",
|
|
||||||
""Versions"": """",
|
|
||||||
""Changelog"": """",
|
|
||||||
""LinuxBot"": """",
|
|
||||||
""WindowsLauncher"": """",
|
|
||||||
}
|
|
||||||
".Replace(" ", "")
|
|
||||||
);
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task DownloadPluginDatabase(
|
private static async Task DownloadPluginDatabase(
|
||||||
|
|||||||
@@ -163,16 +163,9 @@ public class Program
|
|||||||
private static async Task PreLoadComponents(string[] args)
|
private static async Task PreLoadComponents(string[] args)
|
||||||
{
|
{
|
||||||
await Initialize();
|
await Initialize();
|
||||||
|
|
||||||
if (!Directory.Exists("./Data/Resources") || !File.Exists("./Data/Resources/URLs.json"))
|
|
||||||
await Installer.SetupPluginDatabase();
|
|
||||||
|
|
||||||
|
|
||||||
URLs = new SettingsDictionary<string, string>("./Data/Resources/URLs.json");
|
|
||||||
|
|
||||||
Logger.LogEvent += (message, type, isInternal) =>
|
Logger.LogEvent += (message, type, isInternal) =>
|
||||||
{
|
{
|
||||||
if (isInternal) return;
|
|
||||||
if (type == LogLevel.INFO)
|
if (type == LogLevel.INFO)
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
else if (type == LogLevel.WARNING)
|
else if (type == LogLevel.WARNING)
|
||||||
@@ -186,6 +179,12 @@ public class Program
|
|||||||
Console.ResetColor();
|
Console.ResetColor();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!Directory.Exists("./Data/Resources") || !File.Exists("./Data/Resources/URLs.json"))
|
||||||
|
await Installer.SetupPluginDatabase();
|
||||||
|
|
||||||
|
|
||||||
|
URLs = new SettingsDictionary<string, string>("./Data/Resources/URLs.json");
|
||||||
|
|
||||||
|
|
||||||
Console.WriteLine("Loading resources ...");
|
Console.WriteLine("Loading resources ...");
|
||||||
|
|
||||||
@@ -212,8 +211,7 @@ public class Program
|
|||||||
Logger.Log(ex.ToString(), "Bot", LogLevel.ERROR);
|
Logger.Log(ex.ToString(), "Bot", LogLevel.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var onlineSettingsList = await ServerCom.ReadTextFromURL(URLs["Versions"]);
|
var onlineSettingsList = await ServerCom.ReadTextFromURL(URLs["Versions"]);
|
||||||
foreach (var key in onlineSettingsList)
|
foreach (var key in onlineSettingsList)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.IO;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using PluginManager.Bot;
|
using PluginManager.Bot;
|
||||||
using PluginManager.Others;
|
using PluginManager.Others;
|
||||||
|
|||||||
17
PluginManager/Interfaces/Exceptions/IException.cs
Normal file
17
PluginManager/Interfaces/Exceptions/IException.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace PluginManager.Interfaces.Exceptions;
|
||||||
|
|
||||||
|
public interface IException
|
||||||
|
{
|
||||||
|
public List<string> Messages { get; set; }
|
||||||
|
public bool isFatal { get; }
|
||||||
|
public string GenerateFullMessage();
|
||||||
|
public void HandleException();
|
||||||
|
|
||||||
|
public IException AppendError(string message);
|
||||||
|
|
||||||
|
public IException AppendError(List<string> messages);
|
||||||
|
public IException IsFatal(bool isFatal = true);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -39,3 +39,9 @@ public enum InternalActionRunType
|
|||||||
ON_STARTUP,
|
ON_STARTUP,
|
||||||
ON_CALL
|
ON_CALL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal enum ExceptionExitCode : int
|
||||||
|
{
|
||||||
|
CONFIG_FAILED_TO_LOAD = 1,
|
||||||
|
CONFIG_KEY_NOT_FOUND = 2,
|
||||||
|
}
|
||||||
|
|||||||
91
PluginManager/Others/Exceptions/ConfigFailedToLoad.cs
Normal file
91
PluginManager/Others/Exceptions/ConfigFailedToLoad.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PluginManager.Interfaces.Exceptions;
|
||||||
|
|
||||||
|
namespace PluginManager.Others.Exceptions;
|
||||||
|
|
||||||
|
public class ConfigFailedToLoad : IException
|
||||||
|
{
|
||||||
|
public List<string>? Messages { get; set; }
|
||||||
|
public bool isFatal { get; private set; }
|
||||||
|
public string? File { get; }
|
||||||
|
|
||||||
|
|
||||||
|
public ConfigFailedToLoad(string message, bool isFatal, string file)
|
||||||
|
{
|
||||||
|
this.isFatal = isFatal;
|
||||||
|
Messages = new List<string>() {message};
|
||||||
|
this.File = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigFailedToLoad(string message, bool isFatal)
|
||||||
|
{
|
||||||
|
this.isFatal = isFatal;
|
||||||
|
Messages = new List<string>() {message};
|
||||||
|
this.File = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigFailedToLoad(string message)
|
||||||
|
{
|
||||||
|
this.isFatal = false;
|
||||||
|
Messages = new List<string>() {message};
|
||||||
|
this.File = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GenerateFullMessage()
|
||||||
|
{
|
||||||
|
string messages = "";
|
||||||
|
foreach (var message in Messages)
|
||||||
|
{
|
||||||
|
messages += message + "\n";
|
||||||
|
}
|
||||||
|
return $"\nMessage: {messages}\nIsFatal: {isFatal}\nFile: {File ?? "null"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HandleException()
|
||||||
|
{
|
||||||
|
if (isFatal)
|
||||||
|
{
|
||||||
|
Config.Logger.Log(GenerateFullMessage(), LogLevel.CRITICAL, true);
|
||||||
|
Environment.Exit((int)ExceptionExitCode.CONFIG_FAILED_TO_LOAD);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.Logger.Log(GenerateFullMessage(), LogLevel.WARNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IException AppendError(string message)
|
||||||
|
{
|
||||||
|
Messages.Add(message);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IException AppendError(List<string> messages)
|
||||||
|
{
|
||||||
|
Messages.AddRange(messages);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IException IsFatal(bool isFatal = true)
|
||||||
|
{
|
||||||
|
this.isFatal = isFatal;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static ConfigFailedToLoad CreateError(string message, bool isFatal, string? file = null)
|
||||||
|
{
|
||||||
|
if (file is not null)
|
||||||
|
return new ConfigFailedToLoad(message, isFatal, file);
|
||||||
|
return new ConfigFailedToLoad(message, isFatal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConfigFailedToLoad CreateError(string message)
|
||||||
|
{
|
||||||
|
return new ConfigFailedToLoad(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
75
PluginManager/Others/Exceptions/ConfigNoKeyWasPresent.cs
Normal file
75
PluginManager/Others/Exceptions/ConfigNoKeyWasPresent.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PluginManager.Interfaces.Exceptions;
|
||||||
|
|
||||||
|
namespace PluginManager.Others.Exceptions;
|
||||||
|
|
||||||
|
public class ConfigNoKeyWasPresent: IException
|
||||||
|
{
|
||||||
|
public List<string> Messages { get; set; }
|
||||||
|
public bool isFatal { get; private set; }
|
||||||
|
|
||||||
|
public ConfigNoKeyWasPresent(string message, bool isFatal)
|
||||||
|
{
|
||||||
|
this.Messages = new List<string>() { message };
|
||||||
|
this.isFatal = isFatal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigNoKeyWasPresent(string message)
|
||||||
|
{
|
||||||
|
this.Messages = new List<string>() { message };
|
||||||
|
this.isFatal = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GenerateFullMessage()
|
||||||
|
{
|
||||||
|
string messages = "";
|
||||||
|
foreach (var message in Messages)
|
||||||
|
{
|
||||||
|
messages += message + "\n";
|
||||||
|
}
|
||||||
|
return $"\nMessage: {messages}\nIsFatal: {isFatal}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HandleException()
|
||||||
|
{
|
||||||
|
if (isFatal)
|
||||||
|
{
|
||||||
|
|
||||||
|
Config.Logger.Log(GenerateFullMessage(), LogLevel.CRITICAL, true);
|
||||||
|
Environment.Exit((int)ExceptionExitCode.CONFIG_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.Logger.Log(GenerateFullMessage(), LogLevel.WARNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IException AppendError(string message)
|
||||||
|
{
|
||||||
|
Messages.Add(message);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IException AppendError(List<string> messages)
|
||||||
|
{
|
||||||
|
Messages.AddRange(messages);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IException IsFatal(bool isFatal = true)
|
||||||
|
{
|
||||||
|
this.isFatal = isFatal;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConfigNoKeyWasPresent CreateError(string message)
|
||||||
|
{
|
||||||
|
return new ConfigNoKeyWasPresent(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConfigNoKeyWasPresent CreateError(string message, bool isFatal)
|
||||||
|
{
|
||||||
|
return new ConfigNoKeyWasPresent(message, isFatal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ public class DBLogger
|
|||||||
public IReadOnlyList<LogMessage> Logs => LogHistory;
|
public IReadOnlyList<LogMessage> Logs => LogHistory;
|
||||||
public IReadOnlyList<LogMessage> Errors => ErrorHistory;
|
public IReadOnlyList<LogMessage> Errors => ErrorHistory;
|
||||||
|
|
||||||
public event LogHandler LogEvent;
|
public event LogHandler? LogEvent;
|
||||||
|
|
||||||
public void Log(string message, LogLevel type = LogLevel.INFO)
|
public void Log(string message, LogLevel type = LogLevel.INFO)
|
||||||
{
|
{
|
||||||
@@ -52,8 +52,7 @@ public class DBLogger
|
|||||||
|
|
||||||
public void Log(LogMessage message)
|
public void Log(LogMessage message)
|
||||||
{
|
{
|
||||||
if (LogEvent is not null)
|
LogEvent?.Invoke(message.Message, message.Type);
|
||||||
LogEvent?.Invoke(message.Message, message.Type);
|
|
||||||
|
|
||||||
if (message.Type != LogLevel.ERROR && message.Type != LogLevel.CRITICAL)
|
if (message.Type != LogLevel.ERROR && message.Type != LogLevel.CRITICAL)
|
||||||
LogHistory.Add(message);
|
LogHistory.Add(message);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System.Collections;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using PluginManager.Others.Exceptions;
|
||||||
|
|
||||||
namespace PluginManager.Others;
|
namespace PluginManager.Others;
|
||||||
|
|
||||||
@@ -10,13 +10,16 @@ public class SettingsDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
|||||||
{
|
{
|
||||||
public string? _file { get; }
|
public string? _file { get; }
|
||||||
private IDictionary<TKey, TValue>? _dictionary;
|
private IDictionary<TKey, TValue>? _dictionary;
|
||||||
|
|
||||||
public SettingsDictionary(string? file)
|
public SettingsDictionary(string? file)
|
||||||
{
|
{
|
||||||
_file = file;
|
_file = file;
|
||||||
if (!LoadFromFile())
|
if (!LoadFromFile())
|
||||||
{
|
{
|
||||||
throw new Exception($"Failed to load {file}. Please check the file and try again.");
|
ConfigFailedToLoad.CreateError("Failed to load config")
|
||||||
|
.AppendError("The file is empty or does not exist")
|
||||||
|
.IsFatal()
|
||||||
|
.HandleException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,8 +34,13 @@ public class SettingsDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
|||||||
if (!string.IsNullOrEmpty(_file))
|
if (!string.IsNullOrEmpty(_file))
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (File.Exists(_file)){
|
if (File.Exists(_file))
|
||||||
if (!File.ReadAllText(_file).Contains('{') && !File.ReadAllText(_file).Contains('}'))
|
{
|
||||||
|
string FileContent = File.ReadAllText(_file);
|
||||||
|
if (string.IsNullOrEmpty(FileContent))
|
||||||
|
File.WriteAllText(_file, "{}");
|
||||||
|
|
||||||
|
if(!FileContent.Contains("{") || !FileContent.Contains("}"))
|
||||||
File.WriteAllText(_file, "{}");
|
File.WriteAllText(_file, "{}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -40,9 +48,12 @@ public class SettingsDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
|||||||
_dictionary = JsonManager.ConvertFromJson<IDictionary<TKey, TValue>>(_file).Result;
|
_dictionary = JsonManager.ConvertFromJson<IDictionary<TKey, TValue>>(_file).Result;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch
|
||||||
{
|
{
|
||||||
Config.Logger.Error(e);
|
ConfigFailedToLoad
|
||||||
|
.CreateError("Failed to load config")
|
||||||
|
.IsFatal()
|
||||||
|
.HandleException();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +120,19 @@ public class SettingsDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
|||||||
|
|
||||||
public TValue this[TKey key]
|
public TValue this[TKey key]
|
||||||
{
|
{
|
||||||
get => this._dictionary![key];
|
get
|
||||||
|
{
|
||||||
|
if (this._dictionary!.ContainsKey(key))
|
||||||
|
if(this._dictionary[key] is string s && !string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
|
||||||
|
return this._dictionary[key];
|
||||||
|
|
||||||
|
ConfigNoKeyWasPresent.CreateError($"Key {(key is string ? key : typeof(TKey).Name)} was not present in {_file ?? "config"}")
|
||||||
|
.AppendError("Deleting the file may fix this issue")
|
||||||
|
.IsFatal()
|
||||||
|
.HandleException();
|
||||||
|
|
||||||
|
return default!;
|
||||||
|
}
|
||||||
set => this._dictionary![key] = value;
|
set => this._dictionary![key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user