2026-10-15 09:10:37 +02:00
|
|
|
using Avalonia.Threading;
|
|
|
|
|
|
|
|
|
|
using MeWeb.Shared;
|
|
|
|
|
|
|
|
|
|
namespace MeWeb.App.Services;
|
|
|
|
|
|
|
|
|
|
public static class ErrorLog
|
|
|
|
|
{
|
|
|
|
|
const long MaxBytes = 256 * 1024;
|
|
|
|
|
static readonly string FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MeWeb", "errors.log");
|
|
|
|
|
static readonly Lock Gate = new();
|
|
|
|
|
|
|
|
|
|
public static void Watch()
|
|
|
|
|
{
|
|
|
|
|
Dispatcher.UIThread.UnhandledException += OnDispatcher;
|
|
|
|
|
TaskScheduler.UnobservedTaskException += OnUnobserved;
|
|
|
|
|
AppDomain.CurrentDomain.UnhandledException += OnDomain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Write(Exception error)
|
|
|
|
|
{
|
|
|
|
|
if (error is null) return;
|
|
|
|
|
lock (Gate)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
|
|
|
|
|
if (File.Exists(FilePath) && new FileInfo(FilePath).Length > MaxBytes) File.Delete(FilePath);
|
2026-10-30 22:32:49 +01:00
|
|
|
File.AppendAllText(FilePath, $"{DateTimeOffset.UtcNow:O} me-web? {BuildInfo.Version}{Environment.NewLine}{error}{Environment.NewLine}{Environment.NewLine}");
|
2026-10-15 09:10:37 +02:00
|
|
|
}
|
|
|
|
|
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void OnDispatcher(object sender, DispatcherUnhandledExceptionEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Write(e.Exception);
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void OnUnobserved(object sender, UnobservedTaskExceptionEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Write(e.Exception);
|
|
|
|
|
e.SetObserved();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void OnDomain(object sender, UnhandledExceptionEventArgs e) => Write(e.ExceptionObject as Exception);
|
|
|
|
|
}
|