Two Types of Runtime Error?

So your problem is the opposite of @adrianm’s. His situation does generate a run time error, it’s just not captured. You’re saying that they are not being generated at all, correct?

Rob

No, sorry Rob, it is the same issue - I am just struggling to get everyone on the same page on this one (time zones etc). And Adrian has just not yet seen all of the aspects of it. I have spent a good week looking at this as the issue has potential to be massive for my apps. Adrian very kindly had a quick look in response to my forum post. If you have time run the use case that Adrian has created on an app. You will see that the app does not crash. Yes, the words runtime error are generated in a console window, but I would not call that in itself a runtime error. To be fair the simulator does not crash either, so that behaves the same. The problem Adrian is describing is one manifestation of the same problem. Please look into it in more detail if you can as I really believe this is a serious one…

I agree… all runtime errors should abort program execution.  It is up to the developer to allow the runtime error to be suppressed only if they are sure it won’t destabilise their program - by using a pcall() for example.

There are two issues here and neither are good.  

  1. the runtime errors are not trapped by the unhandledError listener,

  2. sometimes errors are not even raised on callback code (see my second use case above).

This is much more of an issue with heavily network-dependent apps.

In my game for example, players can visit other cities.  This obviously uses a network.request() and processes the response to display another city.  If some invalid data is returned I have no way or trapping the error and the thread simply aborts.  This can leave my game in an unstable state.  If I could trap the error I could roll back the game state and try again (or disable the action).

Hi Corona, is there any update on this?

Non-trappable errors on callbacks are bad but callback code that just stops when the main thread continues is a nightmare.

Thanks

Yes please - an update on this would be useful.  In one of my apps I have over 400 possible locations where we have network calls that could cause an issue.  Refactoring this code with my timer workaround is not ideal.  A solution from Corona would be great…  :slight_smile:

It’s in out of QA and into the queue of bugs to be worked on, but it has not been assigned to an engineer yet.

Rob

I’m looking at this issue and will report back when I have more news.

I agree that the handling of runtime errors needs to be more consistent but I’m not sure that a programming methodology that depends on suppressing them is a recipe for success.  In the cited example, relying on a runtime error when getting an unexpected result from a network call is all very well but what if the bad result just causes incorrect behavior in the game and doesn’t raise a runtime error?  The consistency of the data needs to be checked whether or not runtime errors are generated (the good news is that TCP/IP is a reliable method of communication and, if you receive the number of bytes the servers says it sent, you can assume the data is good presuming the server is reliable).

Note that even when the unhandledError listener is working correctly, the current Lua context stops execution at the point of the error and the code in the unhandledError listener is then run and the context ends.  You can’t continue from a runtime error in Lua.  The  unhandledError listener just allows you to know when one happened (when it’s working correctly).

Also, divide by zero doesn’t cause a runtime error in Lua:   5 / 0 evaluates to inf

Perry, firstly I really appreciate you looking at this. I am sure there are lots of priorities on your desk. I am still not sure in your comment above if you have understand our concerns. It is not the data we have a concern with. Your are of course correct, we must check that the data has been returned and is in good order. The issue is that in the current release ANY code called after that network call, regardless if it is doing something with data or not, if any code creates an error the app will not terminate. It may broadcast a message to the output window stating “runtime error”, but for the user there is no indication that there has been an error. The app continues to function, although the code on that thread would have stopped executing. An example could be, scene loads, on load the app gets some data in terms of scene layout, after the data is returned it calls a function SetupScene. That function could do a lot - however if there is any bug in that code, there is currently no way of catching it. In fact even in development you will only see the error if you have your eye on the output window. There is nothing in the app to tell you there is an error. From the user perspective they will see nothing to indicate there is an issue and the app will continue to “work” (although in a potentially invalid state). I have been around development a bit Perry and this seems fundamental to me. There has to be consistency of behaviour with the platform with regards any code failure.

@Perry, thank you for looking into this.  I’ve been using Corona for years and I don’t remember this issue a year or so ago?

I get what you are saying but I stand by a = a + nil is a trappable error irrespective of the context or thread it is executed on.

Just so I’m clear, it’s only network request callbacks that have this issue, correct?

I’ve tested various other kinds of listeners (e.g. tap ) and all stop the app’s execution if they encounter a runtime error (and showRuntimeErrors is set appropriately).  A fix for network listeners will be forthcoming after some more testing.

These are the only callbacks that I have seen this issue with.

@Perry, is try… catch… finally…  design pattern ever going to be in the SDK?  It is so useful in other languages.

@Perry, I was doing some more research today and found another area that is affected.  I use a lot of scene overlays - infact apart from my main scene every other scene is an overlay.  I am still using Storyboard (but I doubt this makes any difference as this is out of scope for Storyboard code).

I use scene:overlayEnded() to process responses from my overlays.  Often I will call functions from the callback to handle certain responses, update UI or change things in my game.  I noticed today that one of those functions was silently failing - no runtime error and nothing in the console.  Ironically it was hitting a divide by 0 and processing halted without any form of error.  When I added an “if 0 don’t divide” check and magically the function now completes as expected.

So functions fired from callbacks, not only network callbacks is also affected.  I can’t really post code as I was nested 4 functions deep.

In summary, whilst 1/0 may not raise an error per sae, id does silently break code execution in callback functions.

I can’t speak to how the logic in your app handles the divide by zero in question but a divide by zero is not an error and does not affect the flow of execution (unless, obviously,  said flow depends on the result of the divide which is likely or the divide would be unnecessary).

Put these lines in a listener (or anywhere else) and they will always both be executed (they are for me):

print("Dividing by zero: ", 5 / 0) print("After dividing by zero")

If you still think it’s a problem, send me a minimal app that demonstrates the issue.

Hi Perry

Can you confirm if you just want a minimal app for the divide by zero or for my original post?  I thought that it was clear what the issue was and that it had been confirmed to be a problem.

I have not been mentioning divide by zero and I am worried that that has not become a distraction from what the original problem was - e.g. any call placed within a network.request listener will not generate a “true” runtime error.

BTW - in you above post you mention Print to validate that the app continues to run - the print statement outputs to the build window.  If you read earlier posts the build window is where the runtime error is output.  The issue is that in the App (and the Corona Simulator)  no error is generated (even though an error is detailed in the build window).

The Daily Build with the fix for this issue (that runtime errors in network listeners did not display an error dialog in debug builds nor did they run an unhandledError listener if one was defined) is available:  CoronaSDK 2017.3075.  Note that by default non-debug builds have never displayed error dialogs for runtime errors (you can control this with showRuntimeErrors).

In Lua, divide by zero is not an error.

And, in any case, the issue was that although an error had occurred (and a message was logged) and the execution of that Lua context (the listener) had stopped, there was no way to know this logically in the rest of the program (like other errors it was logged to the Corona Console).  A print statement after the location of the error does indicate whether the execution of the Lua context has stopped or not.  A print statement appearing after a divide by zero demonstrates that is it not an error.  The issue has never been that runtime errors were not occurring when they should, the issue was that an error dialog wasn’t being displayed if they occurred in a network listener and that an unhandledError listener didn’t work there either.

I would also council that paying attention to what’s in the Corona Console while developing an app pays dividends.  Errors and warnings are highlighted or you can search for “error” or “warning” if you have a lot of console output of your own (on Mac, errors also appear in the drop-down menu below the main console window).  If you have suggestions for ways to make the Corona Console more useful/usable, please let me know.

Thanks Perry.  Is  try… catch… finally…  design pattern ever going to be in the SDK?

This is especially useful for operations that can error like disk IO and network IO.  At the moment Lua throws an error and code execution stops which can be problematic.

For example, in my game players can load other players cities.  This requires downloading a large 2D array where each element is a varying length CSV.  I crunch the data to the absolute minimum to keep bandwidth down.  If there is ever an error in this process the callback stops execution and leaves a zombie-state.  

With a try…catch I can handle the error and either try the download again, prompt the user and/or restore previous state.

Lua doesn’t support the try-catch pattern. Instead it uses pcall() or protected call and error() in conjunction with if-then-else statements. See:

https://www.lua.org/pil/8.4.html

Rob

Thanks Perry and Rob for looking at this.  Also thank you to Adrian for helping out with the analysis.  Really quick turn around…  :slight_smile:

Hello guys,

I would like to report that this issue has been fixed starting from 2017.3109