Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.Net.Sockets.SocketException (995) -System.IO.IOException #90338

Closed
mgungorchamp opened this issue Aug 10, 2023 · 7 comments
Closed

System.Net.Sockets.SocketException (995) -System.IO.IOException #90338

mgungorchamp opened this issue Aug 10, 2023 · 7 comments
Assignees
Labels
area-System.Net.Sockets needs-author-action An issue or pull request that requires more info or actions from the author.
Milestone

Comments

@mgungorchamp
Copy link

mgungorchamp commented Aug 10, 2023

Description

My app is having tons of these exceptions, I am not sure what I am doing wrong. I am catching them via global exception handling.
This does not crash my app but it does not feel right and does not give me confidence in my app in the long run.

System.Exception: CurrentDomain_FirstChanceException
 ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
 ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---Time: 8/10/2023 1:23:18 PM
Error: Unhandled Exception
System.Exception: CurrentDomain_FirstChanceException
 ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
 ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)
   at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](Memory`1 buffer, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---Time: 8/10/2023 1:23:18 PM
Error: Unhandled Exception
System.Exception: CurrentDomain_FirstChanceException
 ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
 ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)
   at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](Memory`1 buffer, CancellationToken cancellationToken)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   --- End of inner exception stack trace

Reproduction Steps

Just start running my app to access API services via HttpClient - use c IHttpClientFactory _httpClientFactory to create it. I followed all the best practices.

Expected behavior

Should work fine...

Actual behavior

Throws exceptions.

Regression?

Nope

Known Workarounds

Catching with global exception handlers

For ANDROID

public class MainActivity : MauiAppCompatActivity
{
    
    // In MainActivity
    //Ref:https://peterno.wordpress.com/2015/04/15/unhandled-exception-handling-in-ios-and-android-with-xamarin/
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
        AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;

        TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;

        Android.Runtime.AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser;


        //Xamarin.Forms.Forms.Init(this, bundle);
        DisplayCrashReport();

        //var app = new App();
        //LoadApplication(app);
    }

    private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs e)
    {
        var newExc = new Exception("AndroidEnvironment_UnhandledExceptionRaiser", e.Exception);
        System.Diagnostics.Debug.WriteLine($"**********************************  AndroidEnvironment_UnhandledExceptionRaiser! Details: {e.Exception.ToString()}");
        

        LogUnhandledException(newExc);
    }

    #region Error handling
    private static void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs unobservedTaskExceptionEventArgs)
    {
        var newExc = new Exception("TaskSchedulerOnUnobservedTaskException", unobservedTaskExceptionEventArgs.Exception);
        System.Diagnostics.Debug.WriteLine($"**********************************  TaskSchedulerOnUnobservedTaskException! Details: {unobservedTaskExceptionEventArgs.Exception.ToString()}");

        LogUnhandledException(newExc);
    }
    private static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
    {
        var newExc = new Exception("TaskSchedulerOnUnobservedTaskException", e.Exception);

        System.Diagnostics.Debug.WriteLine($"********************************** FirstChance EXCEPTION! Details: {e.Exception.ToString()}");

        LogUnhandledException(newExc);
    }

    private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
    {
        var newExc = new Exception("CurrentDomainOnUnhandledException", unhandledExceptionEventArgs.ExceptionObject as Exception);
        System.Diagnostics.Debug.WriteLine($"**********************************  Unhandled Exception! Details: {unhandledExceptionEventArgs.ExceptionObject.ToString()}");

        LogUnhandledException(newExc);
    }

    internal static void LogUnhandledException(Exception exception)
    {
        try
        {
            const string errorFileName = "Fatal.log";
            var libraryPath = FileSystem.CacheDirectory ;//Android.OS.Environment.DownloadCacheDirectory.Path;   // iOS: Environment.SpecialFolder.Resources
            var errorFilePath = Path.Combine(libraryPath, errorFileName);
            var errorMessage = String.Format("\nTime: {0}\r\nError: Unhandled Exception\r\n{1}",
            DateTime.Now, exception.ToString());
            File.WriteAllText(errorFilePath, errorMessage);

            // Log to Android Device Logging.
            Android.Util.Log.Error("Crash Report", errorMessage);
        }
        catch(Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"**********************************  Unhandled Exception! {ex.Message}");
        }
    }

    //<summary>
    // If there is an unhandled exception, the exception information is diplayed 
    // on screen the next time the app is started (only in debug configuration)
    //</summary>
    [Conditional("DEBUG")]
    private void DisplayCrashReport()
    {
        const string errorFilename = "Fatal.log";
        var libraryPath = FileSystem.CacheDirectory;// Android.OS.Environment.DownloadCacheDirectory.Path;
        var errorFilePath = Path.Combine(libraryPath, errorFilename);

        if (!File.Exists(errorFilePath))
        {
            return;
        }

        var errorText = File.ReadAllText(errorFilePath);
        new AlertDialog.Builder(this)
            .SetPositiveButton("Clear", (sender, args) =>
            {
                File.Delete(errorFilePath);
            })
            .SetNegativeButton("Close", (sender, args) =>
            {
                // User pressed Close.
            })
            .SetMessage(errorText)
            .SetTitle("Crash Report")
            .Show();
    } 
 #endregion  
}

FOR WINDOWS

public partial class App : MauiWinUIApplication
{
    /// <summary>
    /// Initializes the singleton application object.  This is the first line of authored code
    /// executed, and as such is the logical equivalent of main() or WinMain().
    /// </summary>
    /// 
    private readonly ILogger _logger;
    public App()
    {
        this.InitializeComponent();
        _logger = Utilities.Logger(nameof(App) + "WindowsMKG");

        AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
        Microsoft.UI.Xaml.Application.Current.UnhandledException += Current_UnhandledException;
    }

    private void Current_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"**********************************  Microsoft.UI.Xaml.Application.Current.UnhandledException! Details: {e.Exception.ToString()}");
        _logger.LogError($"**********************************  Microsoft.UI.Xaml.Application.Current.UnhandledException! Details: {e.Exception.ToString()}");
        var newExc = new Exception("Microsoft.UI.Xaml.Application.Current.UnhandledException", e.Exception);
        LogUnhandledException(newExc);
    }

    //Ref: https://peterno.wordpress.com/2015/04/15/unhandled-exception-handling-in-ios-and-android-with-xamarin/
    // https://gist.github.com/mattjohnsonpint/7b385b7a2da7059c4a16562bc5ddb3b7
    // https://github.com/dotnet/maui/discussions/653

    #region Error handling
    private void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
    {
        
        System.Diagnostics.Debug.WriteLine($"**********************************  TaskSchedulerOnUnobservedTaskException! Details: {e.Exception.ToString()}");
        _logger.LogError($"**********************************  TaskSchedulerOnUnobservedTaskException! Details: {e.Exception.ToString()}");
        //throw new NotImplementedException();
        var newExc = new Exception("TaskSchedulerOnUnobservedTaskException", e.Exception);
        LogUnhandledException(newExc);
    }

    private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"**********************************  Unhandled Exception! Details: {e.ExceptionObject.ToString()}");
        _logger.LogError($"**********************************  Unhandled Exception! Details: {e.ExceptionObject.ToString()}");
        //throw new NotImplementedException();
        var newExc = new Exception("CurrentDomain_UnhandledException " + e.ExceptionObject.ToString());
        LogUnhandledException(newExc);
    }
    private void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"********************************** FirstChance EXCEPTION! Details: {e.Exception.ToString()}");
        _logger.LogError($"********************************** FirstChance EXCEPTION! Details: {e.Exception.ToString()}");
        var newExc = new Exception("CurrentDomain_FirstChanceException", e.Exception);
        LogUnhandledException(newExc);
    }

    internal void LogUnhandledException(Exception exception)
    {
        try
        {
            const string errorFileName = "Fatal.log";
            var libraryPath = Path.Combine(FileSystem.CacheDirectory, "InfoBoardLogs"); ; // iOS: Environment.SpecialFolder.Resources
            var errorFilePath = Path.Combine(libraryPath, errorFileName);
            var errorMessage = String.Format("Time: {0}\r\nError: Unhandled Exception\r\n{1}",
            DateTime.Now, exception.ToString());
            //File.WriteAllText(errorFilePath, errorMessage);
            File.AppendAllText(errorFilePath, errorMessage);
            // Log to Android Device Logging.
            
            _logger.LogError($"**********************************  Error Logged ! \nDetails at: {errorFilePath} Message {errorMessage}");
        }
        catch (Exception ex)
        {
            _logger.LogError($"**********************************  LogUnhandledException \nException! Details: {ex.Message}");
        }
    }
    [Conditional("DEBUG")]
    private async void DisplayCrashReport()
    {
        const string errorFilename = "Fatal.log";
        var libraryPath = Path.Combine(FileSystem.CacheDirectory, "InfoBoardLogs"); ;
        var errorFilePath = Path.Combine(libraryPath, errorFilename);

        if (!File.Exists(errorFilePath))
        {
            return;
        }

        var errorText = File.ReadAllText(errorFilePath);

        var toast = Toast.Make($"Crash Report {errorText}", ToastDuration.Long);
        
        await toast.Show();
        
        File.Delete(errorFilePath);        
    }
#endregion

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

Configuration

Here is my code
.NET MAUI app
https://github.com/mgungorchamp/InfoBoard/tree/SoloPage-Analytics

Other information

Here is the caught exception trace.
dotnet/maui#16679

System.Exception: CurrentDomain_FirstChanceException
 ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
 ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---Time: 8/10/2023 1:23:18 PM
Error: Unhandled Exception
System.Exception: CurrentDomain_FirstChanceException
 ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
 ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)
   at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](Memory`1 buffer, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---Time: 8/10/2023 1:23:18 PM
Error: Unhandled Exception
System.Exception: CurrentDomain_FirstChanceException
 ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
 ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)
   at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](Memory`1 buffer, CancellationToken cancellationToken)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   --- End of inner exception stack trace
@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Aug 10, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Aug 10, 2023
@ghost
Copy link

ghost commented Aug 10, 2023

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

My app is having tons of these exceptions, I am not sure what I am doing wrong. I am catching them via global exception handling.
This does not crash my app but it does not feel right and does not give me confidence in my app in the long run.

System.Exception: CurrentDomain_FirstChanceException
---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
--- End of inner exception stack trace ---
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
--- End of inner exception stack trace ---Time: 8/10/2023 1:23:18 PM
Error: Unhandled Exception
System.Exception: CurrentDomain_FirstChanceException
---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
--- End of inner exception stack trace ---
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)
at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](Memory1 buffer, CancellationToken cancellationToken) --- End of inner exception stack trace ---Time: 8/10/2023 1:23:18 PM Error: Unhandled Exception System.Exception: CurrentDomain_FirstChanceException ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request.. ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request. --- End of inner exception stack trace --- at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token) at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](Memory1 buffer, CancellationToken cancellationToken)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
--- End of inner exception stack trace

Reproduction Steps

Just start running my app to access API services via HttpClient - use c IHttpClientFactory _httpClientFactory to create it. I followed all the best practices.

Expected behavior

Should work fine...

Actual behavior

Throws exceptions.

Regression?

Nope

Known Workarounds

Catching with global exception handlers

For ANDROID

public class MainActivity : MauiAppCompatActivity
{

// In MainActivity
//Ref:https://peterno.wordpress.com/2015/04/15/unhandled-exception-handling-in-ios-and-android-with-xamarin/
protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);

    AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
    AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;

    TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;

    Android.Runtime.AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser;


    //Xamarin.Forms.Forms.Init(this, bundle);
    DisplayCrashReport();

    //var app = new App();
    //LoadApplication(app);
}

private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs e)
{
    var newExc = new Exception("AndroidEnvironment_UnhandledExceptionRaiser", e.Exception);
    System.Diagnostics.Debug.WriteLine($"**********************************  AndroidEnvironment_UnhandledExceptionRaiser! Details: {e.Exception.ToString()}");
    

    LogUnhandledException(newExc);
}

#region Error handling
private static void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs unobservedTaskExceptionEventArgs)
{
    var newExc = new Exception("TaskSchedulerOnUnobservedTaskException", unobservedTaskExceptionEventArgs.Exception);
    System.Diagnostics.Debug.WriteLine($"**********************************  TaskSchedulerOnUnobservedTaskException! Details: {unobservedTaskExceptionEventArgs.Exception.ToString()}");

    LogUnhandledException(newExc);
}
private static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
    var newExc = new Exception("TaskSchedulerOnUnobservedTaskException", e.Exception);

    System.Diagnostics.Debug.WriteLine($"********************************** FirstChance EXCEPTION! Details: {e.Exception.ToString()}");

    LogUnhandledException(newExc);
}

private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
    var newExc = new Exception("CurrentDomainOnUnhandledException", unhandledExceptionEventArgs.ExceptionObject as Exception);
    System.Diagnostics.Debug.WriteLine($"**********************************  Unhandled Exception! Details: {unhandledExceptionEventArgs.ExceptionObject.ToString()}");

    LogUnhandledException(newExc);
}

internal static void LogUnhandledException(Exception exception)
{
    try
    {
        const string errorFileName = "Fatal.log";
        var libraryPath = FileSystem.CacheDirectory ;//Android.OS.Environment.DownloadCacheDirectory.Path;   // iOS: Environment.SpecialFolder.Resources
        var errorFilePath = Path.Combine(libraryPath, errorFileName);
        var errorMessage = String.Format("\nTime: {0}\r\nError: Unhandled Exception\r\n{1}",
        DateTime.Now, exception.ToString());
        File.WriteAllText(errorFilePath, errorMessage);

        // Log to Android Device Logging.
        Android.Util.Log.Error("Crash Report", errorMessage);
    }
    catch(Exception ex)
    {
        System.Diagnostics.Debug.WriteLine($"**********************************  Unhandled Exception! {ex.Message}");
    }
}

//<summary>
// If there is an unhandled exception, the exception information is diplayed 
// on screen the next time the app is started (only in debug configuration)
//</summary>
[Conditional("DEBUG")]
private void DisplayCrashReport()
{
    const string errorFilename = "Fatal.log";
    var libraryPath = FileSystem.CacheDirectory;// Android.OS.Environment.DownloadCacheDirectory.Path;
    var errorFilePath = Path.Combine(libraryPath, errorFilename);

    if (!File.Exists(errorFilePath))
    {
        return;
    }

    var errorText = File.ReadAllText(errorFilePath);
    new AlertDialog.Builder(this)
        .SetPositiveButton("Clear", (sender, args) =>
        {
            File.Delete(errorFilePath);
        })
        .SetNegativeButton("Close", (sender, args) =>
        {
            // User pressed Close.
        })
        .SetMessage(errorText)
        .SetTitle("Crash Report")
        .Show();
} 

#endregion
}

FOR WINDOWS

public partial class App : MauiWinUIApplication
{
///


/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
///

///
private readonly ILogger _logger;
public App()
{
this.InitializeComponent();
_logger = Utilities.Logger(nameof(App) + "WindowsMKG");

    AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
    TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
    Microsoft.UI.Xaml.Application.Current.UnhandledException += Current_UnhandledException;
}

private void Current_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
{
    System.Diagnostics.Debug.WriteLine($"**********************************  Microsoft.UI.Xaml.Application.Current.UnhandledException! Details: {e.Exception.ToString()}");
    _logger.LogError($"**********************************  Microsoft.UI.Xaml.Application.Current.UnhandledException! Details: {e.Exception.ToString()}");
    var newExc = new Exception("Microsoft.UI.Xaml.Application.Current.UnhandledException", e.Exception);
    LogUnhandledException(newExc);
}

//Ref: https://peterno.wordpress.com/2015/04/15/unhandled-exception-handling-in-ios-and-android-with-xamarin/
// https://gist.github.com/mattjohnsonpint/7b385b7a2da7059c4a16562bc5ddb3b7
// https://github.com/dotnet/maui/discussions/653

#region Error handling
private void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
    
    System.Diagnostics.Debug.WriteLine($"**********************************  TaskSchedulerOnUnobservedTaskException! Details: {e.Exception.ToString()}");
    _logger.LogError($"**********************************  TaskSchedulerOnUnobservedTaskException! Details: {e.Exception.ToString()}");
    //throw new NotImplementedException();
    var newExc = new Exception("TaskSchedulerOnUnobservedTaskException", e.Exception);
    LogUnhandledException(newExc);
}

private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    System.Diagnostics.Debug.WriteLine($"**********************************  Unhandled Exception! Details: {e.ExceptionObject.ToString()}");
    _logger.LogError($"**********************************  Unhandled Exception! Details: {e.ExceptionObject.ToString()}");
    //throw new NotImplementedException();
    var newExc = new Exception("CurrentDomain_UnhandledException " + e.ExceptionObject.ToString());
    LogUnhandledException(newExc);
}
private void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
    System.Diagnostics.Debug.WriteLine($"********************************** FirstChance EXCEPTION! Details: {e.Exception.ToString()}");
    _logger.LogError($"********************************** FirstChance EXCEPTION! Details: {e.Exception.ToString()}");
    var newExc = new Exception("CurrentDomain_FirstChanceException", e.Exception);
    LogUnhandledException(newExc);
}

internal void LogUnhandledException(Exception exception)
{
    try
    {
        const string errorFileName = "Fatal.log";
        var libraryPath = Path.Combine(FileSystem.CacheDirectory, "InfoBoardLogs"); ; // iOS: Environment.SpecialFolder.Resources
        var errorFilePath = Path.Combine(libraryPath, errorFileName);
        var errorMessage = String.Format("Time: {0}\r\nError: Unhandled Exception\r\n{1}",
        DateTime.Now, exception.ToString());
        //File.WriteAllText(errorFilePath, errorMessage);
        File.AppendAllText(errorFilePath, errorMessage);
        // Log to Android Device Logging.
        
        _logger.LogError($"**********************************  Error Logged ! \nDetails at: {errorFilePath} Message {errorMessage}");
    }
    catch (Exception ex)
    {
        _logger.LogError($"**********************************  LogUnhandledException \nException! Details: {ex.Message}");
    }
}
[Conditional("DEBUG")]
private async void DisplayCrashReport()
{
    const string errorFilename = "Fatal.log";
    var libraryPath = Path.Combine(FileSystem.CacheDirectory, "InfoBoardLogs"); ;
    var errorFilePath = Path.Combine(libraryPath, errorFilename);

    if (!File.Exists(errorFilePath))
    {
        return;
    }

    var errorText = File.ReadAllText(errorFilePath);

    var toast = Toast.Make($"Crash Report {errorText}", ToastDuration.Long);
    
    await toast.Show();
    
    File.Delete(errorFilePath);        
}

#endregion

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

}

Configuration

Here is my code
.NET MAUI app
https://github.com/mgungorchamp/InfoBoard/tree/SoloPage-Analytics

Other information

Here is the caught exception trace.
dotnet/maui#16679

System.Exception: CurrentDomain_FirstChanceException
---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
--- End of inner exception stack trace ---
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
--- End of inner exception stack trace ---Time: 8/10/2023 1:23:18 PM
Error: Unhandled Exception
System.Exception: CurrentDomain_FirstChanceException
---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
--- End of inner exception stack trace ---
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)
at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](Memory1 buffer, CancellationToken cancellationToken) --- End of inner exception stack trace ---Time: 8/10/2023 1:23:18 PM Error: Unhandled Exception System.Exception: CurrentDomain_FirstChanceException ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request.. ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request. --- End of inner exception stack trace --- at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token) at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](Memory1 buffer, CancellationToken cancellationToken)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
--- End of inner exception stack trace

Author: mgungorchamp
Assignees: -
Labels:

area-System.Net.Sockets, untriaged, needs-area-label

Milestone: -

@vcsjones vcsjones removed the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Aug 14, 2023
@karelz
Copy link
Member

karelz commented Aug 14, 2023

@mgungorchamp which platforms are impacted?
Can you please create minimal repro? (HelloWorld style app)

@karelz karelz added the needs-author-action An issue or pull request that requires more info or actions from the author. label Aug 14, 2023
@ghost
Copy link

ghost commented Aug 14, 2023

This issue has been marked needs-author-action and may be missing some important information.

@mgungorchamp
Copy link
Author

NET MAUI Android and Windows versions have this issue. It's not happening all the time. GitHub source has everything, you need VS 2022, compile and RUN.. and observe the log file generated in the cache folder. https://github.com/mgungorchamp/InfoBoard/tree/SoloPage-Analytics

@ghost ghost removed the needs-author-action An issue or pull request that requires more info or actions from the author. label Aug 16, 2023
@karelz
Copy link
Member

karelz commented Aug 21, 2023

@mgungorchamp would you be able to isolate really the minimal repro on Windows? That would help us route it appropriately.
At this stage, it is still rather involved investigation.

@karelz karelz added the needs-author-action An issue or pull request that requires more info or actions from the author. label Aug 22, 2023
@ghost
Copy link

ghost commented Aug 22, 2023

This issue has been marked needs-author-action and may be missing some important information.

@mgungorchamp
Copy link
Author

It's very difficult to generate since it comes randomly... anyway I am catching up with Global Exception... and the app survives. not a clean solution..

@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Aug 23, 2023
@karelz karelz added this to the 9.0.0 milestone Aug 23, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Sep 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net.Sockets needs-author-action An issue or pull request that requires more info or actions from the author.
Projects
None yet
Development

No branches or pull requests

5 participants