Saltarelle / SaltarelleCompiler

C# to JavaScript compiler – Now http://bridge.net
http://saltarelle-compiler.com
Other
297 stars 74 forks source link

[2.6.2] Exceptions caught inside a cycle are not passed correctly to delegates #417

Closed JechoJekov closed 9 years ago

JechoJekov commented 9 years ago

In the code below the "exc" value inside the "PrintException" method is null instead of the exception passed.

The code prints the following:

Exception is null.

Instead of the error message.

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

        for (var k = 0; k < 1; k++)
        {
            try
            {
                throw new Exception("A generic error.");
            }
            catch (Exception exc)
            {
                var value = 1;
                PrintException(() => Tuple.Create(value, exc));
            }
        }
    }

    static void PrintException(Func<Tuple<int, Exception>> callback)
    {
        var tuple = callback();
        var exc = tuple.Item2;
        if (exc == null)
        {
            Console.WriteLine("Exception is null.");
        }
        else
        {
            Console.WriteLine(exc.Message);
        }
    }
}

The code generated for the main method is:

console.log('Application started.');
for (var k = 0; k < 1; k++) {
    try {
        throw new ss.Exception('A generic error.');
    }
    catch ($t1) {
        var exc = ss.Exception.wrap($t1);
        var value = { $: 1 };
        $QuickView_Test_App_Application.$printException(ss.mkdel({ value: value, exc: exc }, function() {
            return { item1: this.value.$, item2: this.exc.$ };
        }));
    }
}

The reason is that unlike the "value" variable "exc" is not wrapped and thus "exc.$" is undefined.

JechoJekov commented 9 years ago

Workaround: Assign the exception to a local variable and pass it to the delegate instead.

var value = 1;
var exc2 = exc;
PrintException(() => Tuple.Create(value, exc2));

The generated code is as follows:

var exc = ss.Exception.wrap($t1);
var value = { $: 1 };
var exc2 = { $: exc };
$Test_App_Application.$printException(ss.mkdel({ value: value, exc2: exc2 }, function() {
    return { item1: this.value.$, item2: this.exc2.$ };
}));
erik-kallen commented 9 years ago

Yes, this is a bug