Method.invoke() and exception handling?

It seems Method.invoke() does not pass on any exceptions from the invoked method.

So, even if I surround it with a try-catch block, any exceptions happening inside the invoked method will lead to an Unhandled Exception error and crash the app.

class Test {
    function testInvoke() as Void {
        try {
            method( :callback ).invoke();
        } catch ( ex ) {
            // handle the exception
        }
    }
function callback() as Void {
     // This leads to an Unhandled Exception error
throw new InvalidOptionException( "Test" );
    }
}

What would you say, bug, feature, or am I just doing something wrong?

  • OK, after reworking my code to handle exceptions in the invoked functions, and use a singleton to pass the exception to the code calling Method.invoke(), I have a hard time in seeing a "feature" in this.

  • I don't know if you noticed the cost of calling invoke. When I tested it, it was unacceptable for something that runs every second, e.g. onUpdate()

  • I agree it would be better if the exception was passed, but java works somewhat similar, so it's probably not a bug, just not well documented behavior.

  • I agree it would be better if the exception was passed, but java works somewhat similar, so it's probably not a bug, just not well documented behavior.

    My Java experience is a bit dated but I looked into it, and it appears that when invoking a method via reflection in Java, exceptions are propagated to the caller. They're wrapped in an InvocationTargetException, which still allows access to the original exception via its getCause() method.

    I have written a bug report/feature request for this:

    forums.garmin.com/.../method-invoke-does-not-propagate-exceptions

  • I don't know if you noticed the cost of calling invoke. When I tested it, it was unacceptable for something that runs every second, e.g. onUpdate()

    I run small test.

    First, with a relatively heavyweight function:

    class TestInvoke {
        public function invokeByMethod() as Void {
            method( :callback ).invoke();
        }
        public function invokeDirectly() as Void {
            callback();
        }
        public function callback() as Void {
            for( var i = 0; i < 1000; i++ ) {
                var a = 3 * i / 4;
            }
        }
    }

    Here is the profiler output for this:

    Of course the callback() function I used for testing is relatively heavyweight - if it would be lighter, the difference made by Method.invoke() may be more significant.

    So I tried with a lightweight function:

    class TestInvoke {
        public function invokeByMethod() as Void {
            method( :callback ).invoke();
        }
        public function invokeDirectly() as Void {
            callback();
        }
        public function callback() as Void {
            var a = 3;
            var b = 3 * a;
        }
    }

    Here the difference is proportionally much more significant:

    I'll anyway replace Method.invoke() by my own wrapper classes that make a direct call to the function. Since I need a wrapper function anyway to do do the exception handling this is more efficient than using Method.invoke().

  • So you can see... Especially if you have to draw 24x60x60 times per day.

    But my case was much worse. I  tried to make virtualization if objects without coding the new classes and using if's (memory).