75117aa8d3
* Only log errors and observe them if they're speckle related. Others log if possible and let bomb out the app * stacktrace is nullable * Process the exceptions as inner exceptions * Null handling * Change how it's fixed * ToString --------- Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
82 lines
2.9 KiB
C#
82 lines
2.9 KiB
C#
using System.Reflection;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Speckle.Connectors.Common.Threading;
|
|
using Speckle.Connectors.DUI.Bindings;
|
|
using Speckle.Connectors.DUI.Bridge;
|
|
using Speckle.Connectors.DUI.Models;
|
|
using Speckle.Sdk;
|
|
using Speckle.Sdk.Common;
|
|
using Speckle.Sdk.Transports;
|
|
|
|
namespace Speckle.Connectors.DUI;
|
|
|
|
public static class ContainerRegistration
|
|
{
|
|
public static void AddDUI<TThreadContext, TDocumentStore>(this IServiceCollection serviceCollection)
|
|
where TDocumentStore : DocumentModelStore
|
|
where TThreadContext : IThreadContext, new()
|
|
{
|
|
// context always newed up on host app's main/ui thread
|
|
serviceCollection.AddSingleton<IThreadContext>(new TThreadContext());
|
|
serviceCollection.AddSingleton<DocumentModelStore, TDocumentStore>();
|
|
serviceCollection.AddSingleton<IDocumentModelStore>(sp => sp.GetService<DocumentModelStore>());
|
|
|
|
serviceCollection.AddTransient<IBrowserBridge, BrowserBridge>(); // POC: Each binding should have it's own bridge instance
|
|
|
|
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetAssembly(typeof(IdleCallManager)).NotNull());
|
|
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetAssembly(typeof(IServerTransportFactory)).NotNull());
|
|
|
|
serviceCollection.AddSingleton<IBinding, TopLevelExceptionHandlerBinding>(sp =>
|
|
sp.GetRequiredService<TopLevelExceptionHandlerBinding>()
|
|
);
|
|
serviceCollection.AddSingleton<TopLevelExceptionHandlerBinding>();
|
|
serviceCollection.AddSingleton<ITopLevelExceptionHandler, TopLevelExceptionHandler>();
|
|
}
|
|
|
|
public static void UseDUI(this IServiceProvider serviceProvider)
|
|
{
|
|
//observe the unobserved!
|
|
TaskScheduler.UnobservedTaskException += (_, args) =>
|
|
{
|
|
try
|
|
{
|
|
foreach (var exception in args.Exception.InnerExceptions)
|
|
{
|
|
if (TestAndLogStacktrace(serviceProvider, exception))
|
|
{
|
|
args.SetObserved();
|
|
}
|
|
}
|
|
}
|
|
#pragma warning disable CA1031
|
|
catch (Exception e)
|
|
#pragma warning restore CA1031
|
|
{
|
|
Console.WriteLine("Error logging unobserved task exception");
|
|
Console.WriteLine(args.Exception);
|
|
Console.WriteLine(e);
|
|
}
|
|
};
|
|
}
|
|
|
|
private static bool TestAndLogStacktrace(IServiceProvider serviceProvider, Exception exception)
|
|
{
|
|
var stackTrace = exception.ToString();
|
|
if (stackTrace.IndexOf("Speckle", StringComparison.InvariantCultureIgnoreCase) <= 0)
|
|
{
|
|
serviceProvider
|
|
.GetRequiredService<ILoggerFactory>()
|
|
.CreateLogger("UnobservedTaskException")
|
|
.LogInformation(exception, "Non-Speckle unobserved task exception");
|
|
return false;
|
|
}
|
|
|
|
serviceProvider
|
|
.GetRequiredService<ILoggerFactory>()
|
|
.CreateLogger("UnobservedTaskException")
|
|
.LogError(exception, "Unobserved task exception");
|
|
return true;
|
|
}
|
|
}
|