Skip to content

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

@mgungorchamp

Description

@mgungorchamp

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions