Files
speckle-sharp-connectors/DUI3/Speckle.Connectors.DUI/ContainerRegistration.cs
T
Adam Hathcock 75117aa8d3 fix(logs) Only log errors and observe them if they're speckle related. (#887)
* 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>
2025-06-09 14:12:34 +00:00

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;
}
}