Exception Handling

At XDC 2019 my session was titled Xojo Design Mistakes (the alternate but way longer title was ‘Thankfully time travel doesn’t exist or my future self might travel back and murder my younger self for the stupid coding mistakes I’ve made’).  These are things that I’ve discovered over the years, both in my own projects and in other peoples projects that are just plain wrong or less than ideal.  This will be an on-going series since I had well over 50 slides and left about 150 out.  So when I get bored I’ll bring these topics up.

Xojo has evolved over the years.  Many of the global framework (the classic framework) classes set an error bit or error code when an error occurred and the developer has to check to see if there is an error and deal with it accordingly.  Many developers don’t check – mainly out of ignorance, and that’s a problem.

The newer (but soon to be deprecated) Xojo framework (and we’ve been told the API 2.0 framework as well) throws Runtime Exceptions to report errors.  The exceptions definitely get your attention because, well, an exception happened.  The problem is that many Xojo developers don’t catch exceptions anywhere in their application.  This results in dialogs like this:

Users hate seeing this and it’s unhelpful to the developer because it tells them NOTHING about the cause of the error.  And, their application quits making the user really unhappy.

The Application object in every Xojo project has an UnhandledException event made to catch any exceptions not caught anywhere else.  It’s declaration is this:

By returning True you can keep the application from quitting.  Just returning true is just as bad, perhaps worse, than the first dialog because the app had an exception and the app might now be in an unknown state and the user has no idea that it happened.  At this point what happens is anyone’s guess.  Silent errors are a bad thing.  Never do this.

A better way is to use the App.UnhandledException event to report that something happened so the user can decide what to do.  Ideally, you’d like to get some information from them so the developer can get an idea of what’s caused the exception.  What were they doing when the exception happened?  What is the stack trace?

If you are are unaware of what the Stack Trace is this is the call stack your app is current in when the exception occurred.  Maybe you called the Pushbutton1.Action that called ClassA.Method1 which called Global.MethodB which called Global.MethodC.  This information (although not as neatly) is in the stack trace.  It is sometimes invaluable in helping find and fix bugs.

BKeeney Software created a generic error reporting system years ago that when put in the App.UnhandledException shows the user a dialog like this when an exception occurs.  You can tailor the message to suit your needs.

We generally don’t quit apps when exceptions are raised, but it is something that some clients want.  The Report Error button then takes them to another dialog asking for more information.  The user can easily bypass this section by pressing OK.  Hopefully your users are nice and they’ll report the error.

If they select the E-Mail Bug Report or Save Text File button without putting anything in the TextField we present a dialog begging them for more information.  Sometimes this works but not always.

Regardless, the next step in the process creates an email or text file.  Sending an email requires the use of the computers built-in email client and we find this has advantages in that we get the users email address.  A sample email goes something like this:

In our email we get the type of exception, the time, the method location, basic system information, the user description (hopefully), and the stack trace.  A vast majority of the time that’s enough to find a bug.  Sometimes it’s not but at least you can email them back.  The text file still requires them to send it to us via email so we helpfully include the support email address.

If you want to play around with this example, please download it from https://www.dropbox.com/s/3uxyqvjf4wvjrpg/Exception%20Handler%201.0.zip?dl=0.  Feel free to use in your own code however it is provided as-is with no warranty.  We cannot provide support.

You need to implement something similar to this exception handling strategy.  It will help your customers provide feedback to you so you can fix bugs.  This seems like the least you should do.  With the upcoming API 2.0 with API’s that throw exceptions rather than setting error codes this will be more important than ever.  I’m sure I’ll talk more about Exception handling strategies once API 2.0 is released.

What other types of things do you do for error reporting?

10 thoughts on “Exception Handling

  1. Years ago I made a similar window and that was separated as BugReporterKit.
    It uses a HTTPSocket to send report to our webserver, where we can email it or put it in a database.

    This may be better than using email client, as HTTP is usually available (not firewall blocked) and an email client may not be configured on the computer.

    With our plugin classes, we also catch unhandled NSExceptions, C++ exceptions on Windows and signals (hard crashes).

    For some crashes of the apps, we even added an out responder to the script on the web server, as some old app versions crash on newer MacOS versions. We fixed it, but the auto responders informs people with older software.

  2. We have HTTP bug submission for clients that don’t have commercial software. Consumers, rightfully, are concerned what’s getting sent to a server. So we give the option of sending it directly in email, or just saving the text file for sending later. That seems to be good enough for most.

    There really are no bad ways of doing this. As long as you have *something* to catch runtime exceptions in Xojo it’s far better than nothing.

    • most of our apps either drop a file on the user’s machine (sometimes text, or json or encrypted file*) that they can either give to their internal support or send to us (depending on the client).

      other apps we use some form of submission via API calls (like to a customer internal help desk system and automagically opens a ticket for the end user).

      different clients want/expect different things.

      under “classic” and “new” framework most Xojo devs dont catch their exceptions (more on classic than new) and exceptions is going to be a punch-to-the-face for them. I can only guess/hope for the best out of the new API2 framework.

      we will see..

      • Yeah, most Xojo developers currently don’t even handle the App.UnhandledException event. I think this is mainly because they don’t need to. This will be critical moving forward with API 2.0.

  3. I just hope people avoid the habit that was prevalent in Java for a while where so many chunks of code just caught everything instead of catching the things they could actually handle
    Folks got into the habit of doing

    // code
    catch exc as RuntimeException
    end try

    or something similar which is just as bad as not checking any error codes

  4. I usually do quite the same as Bob does, it’s part of my framework so to say. But there is one thing Bob did not mention, but which I also do:
    My configuration-file, Sqlite next to app, holds the user’s settings, but also has two tables to keep a lot of environmental variables, OS parameters, Xojo version, Build version, Plugin versions, IP-addresses and connection details etc. The one table contains this data and has a trigger to write a copy of a record to the second table, audit trail, in case something might change. This is just Sqlite functionality. Once an error is reported, the developer sees immediately user’s configuration details, and even more important if something has recently been changed what probably caused the error.

    • Next to the app ?
      Doesn’t that have permissions errors when the user is not an admin on Windows ?

      • Yes. Most of my stuff is I do copy it myself on the user’s machines, and set the security manually..
        I have another desktop project where I ask in a dialog on first launch where to generate/store the configuration details, next to the exe or in the Windows user folder (recommended)

  5. Thanks for posting this, great points. Note that your sample project requires ‘EncodingToURLMBS’ which may not work for those without the MBS Plugins.

Comments are closed.