1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
public static class MauiExceptions
{
#if WINDOWS
private static Exception _lastFirstChanceException;
#endif
// We'll route all unhandled exceptions through this one event.
public static event UnhandledExceptionEventHandler UnhandledException;
static MauiExceptions()
{
// This is the normal event expected, and should still be used.
// It will fire for exceptions from iOS and Mac Catalyst,
// and for exceptions on background threads from WinUI 3.
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
UnhandledException?.Invoke(sender, args);
};
#if IOS || MACCATALYST
// For iOS and Mac Catalyst
// Exceptions will flow through AppDomain.CurrentDomain.UnhandledException,
// but we need to set UnwindNativeCode to get it to work correctly.
//
// See: https://github.com/xamarin/xamarin-macios/issues/15252
ObjCRuntime.Runtime.MarshalManagedException += (_, args) =>
{
args.ExceptionMode = ObjCRuntime.MarshalManagedExceptionMode.UnwindNativeCode;
};
#elif ANDROID
// For Android:
// All exceptions will flow through Android.Runtime.AndroidEnvironment.UnhandledExceptionRaiser,
// and NOT through AppDomain.CurrentDomain.UnhandledException
Android.Runtime.AndroidEnvironment.UnhandledExceptionRaiser += (sender, args) =>
{
UnhandledException?.Invoke(sender, new UnhandledExceptionEventArgs(args.Exception, true));
};
#elif WINDOWS
// For WinUI 3:
//
// * Exceptions on background threads are caught by AppDomain.CurrentDomain.UnhandledException,
// not by Microsoft.UI.Xaml.Application.Current.UnhandledException
// See: https://github.com/microsoft/microsoft-ui-xaml/issues/5221
//
// * Exceptions caught by Microsoft.UI.Xaml.Application.Current.UnhandledException have details removed,
// but that can be worked around by saved by trapping first chance exceptions
// See: https://github.com/microsoft/microsoft-ui-xaml/issues/7160
//
AppDomain.CurrentDomain.FirstChanceException += (_, args) =>
{
_lastFirstChanceException = args.Exception;
};
Microsoft.UI.Xaml.Application.Current.UnhandledException += (sender, args) =>
{
var exception = args.Exception;
if (exception.StackTrace is null)
{
exception = _lastFirstChanceException;
}
UnhandledException?.Invoke(sender, new UnhandledExceptionEventArgs(exception, true));
};
#endif
}
}
|