Skip to content
This repository has been archived by the owner on Mar 9, 2021. It is now read-only.

[2.7.0] Asynchronous tasks swallow exceptions #437

Open
JechoJekov opened this issue Oct 29, 2015 · 0 comments
Open

[2.7.0] Asynchronous tasks swallow exceptions #437

JechoJekov opened this issue Oct 29, 2015 · 0 comments

Comments

@JechoJekov
Copy link

When an async task awaits on another async task and the latter fails with an exception it is not propagated to the initial caller.

public static class Application
{
    public static void Main()
    {
        Console.WriteLine("Application started.");

        Run();
    }

    static async void Run()
    {
        var t = new TestAsync();
        var value = await t.AsyncError1();
        Console.WriteLine(value.ToString());
    }
}

class TestAsync
{
    public async Task<long> AsyncError1()
    {
        var value = await AsyncError2();

        Console.WriteLine(value.ToString());
        Console.WriteLine("Raising an error 1.");

        throw new Exception("This is an error 1.");
    }

    Task<long> AsyncError2()
    {
        Console.WriteLine("Raising an error 2.");

        throw new Exception("This is an error 2.");
    }
}

The code above prints the following on the console:

Application started.
Raising an error 2.

In .NET such exceptions gets raised on a thread-pool thread and crashes the application. However, Saltarelle ignores them.

In the following code:

public static class Application
{
    public static void Main()
    {
        Console.WriteLine("Application started.");

        Run();
    }

    static async void Run()
    {
        try
        {
            var t = new TestAsync();
            var value = await t.AsyncError1();
            Console.WriteLine(value.ToString());
        }
        catch (Exception exc)
        {
            Console.WriteLine("An error occurred during the exception of the first async method: " + exc.Message);
        }
    }
}

class TestAsync
{
    public async Task<long> AsyncError1()
    {
        var value = await AsyncError2();

        Console.WriteLine(value.ToString());
        Console.WriteLine("Raising an error 1.");

        throw new Exception("This is an error 1.");
    }

    Task<long> AsyncError2()
    {
        Console.WriteLine("Raising an error 2.");

        throw new Exception("This is an error 2.");
    }
}

the exception is caught by the "Run" method and displayed on the console:

Application started.
Raising an error 2.
An error occurred during the exception of the first async method: This is an error 2.

The reason is that the "AsyncError1()" method call is awaited inside a try-catch block.

Swallowing the exception may cause parts of the application to fail silently and makes it difficult to track the reason.

IMO if a task fails and there is no continuation callback (as in the case when a task is awaited inside a try-catch block) the exception should still be raised. This will cause it to be displayed on the console and to fire the "window.onerror" event.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant