Finally issues

I’m pretty sure that it’s a known issue that a try {} catch {} finally {} on WebGL will result in the finally {} block never being called, but i just spent a couple of days trying to determine a bug, and found out that its because a try {} finally {} block never runs its finally block (even without the catch).

Is there any way to not have to work around this (a command line argument or something?), and is it ever going to be fixed? It seems especially harmful, in that the finally block is supposed to always execute and generally always has stuff that needs to happen which plainly will never ever execute in WebGL. Also, is this a IL2CPP issue or a emscripten type issue? its very annoying to have to replace try {} finally {/code/} with try {} catch{/code/ throw;}/code/(again) and not so safe in the case where what would normally be in the finally block ends up throwing an exception in the catch block.

For what its worth, the try{} finally{} was in a managed dll.

Does changing the exception settings have any effect on this ?

unfortunately, when i have exception settings on the game always crashes:sweat_smile:

Did you try Full or Explicitly Thrown?
Full is too big for most of the cases, so it crashes. but Explicitly Thrown should work

FYI, that issue will be fixed in 5.1.

thats great. although, are you saying that exception catching being off is what is causing finally blocks not to execute?..

Yes, that too.

“Finally” is implemented using Exception catching mechanics. Since you have disabled Exceptions completely in your WebGL Player Settings, your finally blocks will not be called. You need to set exception support to at least “Explicitly thrown exceptions only” for this to work. I will edit the docs to make this clear.

FYI, “Explicitly thrown exceptions only” mode will be much faster in Unity 5.1.

I think that’s the wrong approach. In standard c# the finally block executes always. That means, if an exception is thrown or not, it runs, even if a return statement is in the try block. I could understand it not executing when an exception is thrown with exceptions off, but otherwise IMO it should execute whether exceptions are on or off when no exception is thrown.

I’m positive that this is likely one of the biggest hurdles to run into, and its almost intrusive to third party managed dll. while i haven’t tested the using(x) statement if dispose actually gets called or not (which is documented as essentially wrapping a try finally statement around the block where Dispose() is called within the generated finally block… if this is not broken, any developer who has understood what it does, and has required extra handling that the using block does not offer (such as passing x by ref), they would fallback to try { } finally {}. And again, to be clear: finally never runs, so essentially all code which is considered sensitive enough put inside of a finally block plainly never runs.

I’d suggest if you have this code:

try {
    Variable.Something();
} finally {
    Variable.Dispose();
}

with exceptions off, IL2CPP or whatever is in charge of removing exception handling should do this:

//try {
    Variable.Something();
//} finally {
    Variable.Dispose();
//}

then people will not have to get clever with making their code less error proof just to support webgl, where the docs clearly state a large penalty for exception catching exist, and any plugin creator targeting the platform is basically going to be at blame for not removing finally statements on their own.

It’s not that easy, right? What if you have return statements anywhere in your code.

I think the real takeaway here is that we should work on making the penalties from exception catching code go away., as all your arguments also apply to exception catching in general. As I wrote, 5.1 is pretty good progress in that direction.

Don’t get me wrong, I wasn’t suggesting it to be easy, infact i have no idea of how unity is doing the regeneration code – but that would be the proper way to do away with exception catching without breaking support. TBH you might as well do away with anything within the try block if your dropping whats in the finally block, it’s essentially the same issue.

But I do hope that explicitly thrown exception catching is proper in 5.1, Does it include exceptions thrown by mscorlib/other managed libraries?

Yes. It also does in 5.0, if you enable it - nothing is changing there. What is changing is that the performance penalty for enabling it is going down a lot in 5.1.