1

I am facing an issue where most exceptions thrown in my .NET MAUI Windows app appear in the Windows Event Viewer as if they are coming from CoreMessagingXP.dll instead of showing the actual managed exception details.

Event Viewer Entry

Example error entry in Event Viewer:

Faulting application name: MyApp.exe, version: 1.0.0.0, time stamp: 0x68760000
Faulting module name: CoreMessagingXP.dll, version: 10.0.26107.1011, time stamp: 0x76d08d1d
Exception code: 0xc000027b
Fault offset: 0x0000000000093b76
Faulting process id: 0x0x91EC
Faulting application start time: 0x0x1DC20AF5C927FCB
Faulting application path: E:\WS\MyApp\bin\Debug\net9.0-windows10.0.19041.0\win10-x64\AppX\MyApp.exe
Faulting module path: C:\Program Files\WindowsApps\Microsoft.WindowsAppRuntime.1.7_7000.522.1444.0_x64__8wekyb3d8bbwe\CoreMessagingXP.dll
Report Id: 0575b91c-aca3-4212-acae-73681ff068e0
Faulting package full name: com.company.myapp_0.0.1.0_x64__yx3b1xs067x9a
Faulting package-relative application ID: App

Reproduction

For testing, I simply threw an exception from the code-behind of a button click. Even in this trivial case, the Event Viewer still shows the crash as CoreMessagingXP.dll.

Debugging the Dump

When I open the generated dump file in Visual Studio, it breaks at KERNELBASE.dll with:

Unhandled exception at 0x00007FFCC8D13B76 (CoreMessagingXP.dll) in MyApp.exe: 
0xC000027B: An application-internal exception has occurred (parameters: 0x000001B1B7019A10, 0x0000000000000001).

Call Stack (excerpt):

> KERNELBASE.dll!00007ffd369321b2()    Unknown
  combase.dll!00007ffd383d5e79()      Unknown
  CoreMessagingXP.dll!00007ffcc8d13b76() Unknown
  CoreMessagingXP.dll!00007ffcc8cc0aad() Unknown
  CoreMessagingXP.dll!00007ffcc8cc4b06() Unknown
  ...
  Microsoft.WinUI.dll!Microsoft.UI.Xaml.Application.Start(...) Unknown
  MyApp.dll!MyApp.WinUI.Program.Main(string[] args) Unknown

Questions

  1. Why does the actual managed exception not show up in the Windows Event Log or the dump file?
  2. How can I configure my MAUI Windows app so that managed exceptions are properly logged and visible in Event Viewer and dumps, instead of being masked as a generic CoreMessagingXP.dll crash?

2 Answers 2

0

The following code works on WinUI 3 and I guess it should also work on MAUI.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.UI.Xaml;

namespace WinUIDemoApp;

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
        this.UnhandledException += App_UnhandledException;
    }

    private void App_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        var logger = Host?.Services.GetService<ILogger<App>>();
        logger?.LogError(e.Exception, "An unhandled exception occurred.");
    }
...
}

Here's the doc for Microsoft.Extensions.Logging.

UPDATE

If the exception is thrown inside an async void method, you need to catch it inside of it:

private async Task SomeAsyncMethod()
{
    throw new Exception("Simulated exception in OnLanguageClicked");
}

private async void OnLanguageClicked(object? sender, EventArgs e)
{
    try
    {
        await SomeAsyncMethod();
    }
    catch (Exception exception)
    {
        var logger = Host?.Services.GetService<ILogger<SomeClass>>();
        logger?.LogError(exception, "An exception occurred.");
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

I have - AppDomain.CurrentDomain.UnhandledException += GlobalExceptionLogger; in app.xaml.cs. this exception handler is not hit when I throw a test exception. If i place a Try catch around the throw statement the exception is getting caught as expected. I wanted a global exception handler which handles the exceptions.
Does this help?
When I throw the exception, the GlobalExceptionLogger is not called. The app crashes. May be the subscribing to AppDomain.CurrentDomain.UnhandledException catches only a specific set of exceptions??
Does that exception crash the app? Are you sure it's not caught and handled? or in an async void method?
Yes, it crashes the windows application. The GlobalExceptionLogger is not called. Yes the throw is in a async void method (click event handler of a button)
I have shared a sample project at -- github.com/manjunath-vadigeri/PopupIssue -- In the main page there is a button with OnLanguageClicked event handler - where I throw the exception. In app.xaml.cs I have subscribed to both Microsoft.Maui.MauiWinUIApplication.Current.UnhandledException and AppDomain.CurrentDomain.UnhandledException but none of these will get hit when the exception is thrown and the WINDOWS app crashes
I updated my answer. To catch exceptions inside async methods, you need to await them. Since you can't await async void methods, you can't catch exceptions outside of them. Check the link in my answer. ;)
0

MAUI on Windows is implemented using WinUI3. WinUI3 itself is a native framework that has bindings/projections for .NET (but also C++), etc.

Anyway in Windows, unless something catches it, a crash will end up in the Event Log. This is the case by default with WinUI3 and MAUI over it, and that's what you see (note that with proper setup and symbols, a developer can investigate that kind of raw reports).

Here is how you can catch it (I've use the System.Diagnostics.EventLog package but you can use any logging facility):

Change Platforms\Windows\App.xaml.cs like this:

public partial class App : MauiWinUIApplication
{
    public App()
    {
        // we handle only our specific exception type in case of
        // unobserved exceptions, best effort for bad coding practises :-)
        AppDomain.CurrentDomain.FirstChanceException +=
            (sender, e) => HandleException(e.Exception as MyException);

        UnhandledException += (sender, e) =>
        {
            // prevent the app from crashing & exit gracefully
            e.Handled = true;
            HandleException(e.Exception);
        };

        InitializeComponent();
    }

    private void HandleException(Exception? ex)
    {
        if (ex == null) return;

        // pick a source that exists like "Application" or create a new one (requires admin rights)
        // here we use ".NET Runtime"
        // see why here https://www.jitbit.com/alexblog/266-writing-to-an-event-log-from-net-without-the-description-for-event-id-nonsense/
        System.Diagnostics.EventLog.WriteEntry(
            ".NET Runtime",
            $"Unhandled exception: {ex.Message}",
            System.Diagnostics.EventLogEntryType.Error,
            1000);

        Exit();
    }

    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

This is the result in Event Viewer:

Event Viewer

Now, why the first line? Because your reproducing code does this:

private async void OnLanguageClicked(object? sender, EventArgs e)
{
    throw new Exception("Simulated exception in OnLanguageClicked");
}

Note with Visual Studio the green swiggles:

swiggles

What it means is the implicit task you're starting with the async keyword is unobserved. It's generally bad practise, and in this case it crashes the native layers underneath (which could handle this in a better way we agree on that...) so you get a real native handled error that you can see in the event viewer.

In this case there are two ways of dealing with this kind of errors:

A: use a custom exception type for all your errors and you can catch it in FirstChanceException handler (there are many other 1st chance exceptions that we don't care about that's why you need a custom one), so for example this would be caught by our handlers:

private async void OnCounterClicked(object? sender, EventArgs e)
{
    throw new MyException("hello from main page");
}

public class MyException : Exception
{
    public MyException(string message) : base(message) { }
}

B: (preferred as it works for types of exceptions), just make sure you don't use this type of void async bad practise code and use this pattern instead:

private void OnCounterClicked(object? sender, EventArgs e)
{
    _ = DoSomethingThatThrows();
}

Task DoSomethingThatThrows()
{
    throw new Exception("hello from main page");
}

4 Comments

I have - AppDomain.CurrentDomain.UnhandledException += GlobalExceptionLogger; in app.xaml.cs and now introduced Microsoft.Maui.MauiWinUIApplication.Current.UnhandledException += (sender, e) as you suggested. None of these exception handlers hit when throw a test exception. If i place a Try catch around the throw statement the exception is getting caught as expected. I wanted a global exception handler which handles the exceptions.
How is your exception thrown? I've done my tests just by doing a throw new Exception("hello from main page"); in a XAML button click handler
I have shared a sample project at -- github.com/manjunath-vadigeri/PopupIssue -- In the main page there is a button with OnLanguageClicked event handler - where I throw the exception. In app.xaml.cs I have subscribed to both Microsoft.Maui.MauiWinUIApplication.Current.UnhandledException and AppDomain.CurrentDomain.UnhandledException but none of these will get hit when the exception is thrown and the WINDOWS app crashes
This is because you use async void, I've updated my answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.