Capturing application wide exceptions.

This might be useful. This is the type of report we generate when there is an unhandled exception. App.UnhandledException sets a “quit” flag, then starts a Timer that opens the user report dialog. The user can get to this window anytime to report non-crashy issues, so the flag tells the app to quit once the user is done in this case. This report is sent to Jira, our issue tracking system. (Personal information is masked here.) We use a Timer in case there is an exception in the bug reporting system so we don’t get an endless loop.

h1. User Description


Opened the claim and this happened

h1. Steps to Reproduce


As above

h1. Severity: Major Problem


h1. Exception Information


A NilObjectException exception occurred

h1. Stack Trace


1. RuntimeRaiseException
2. RaiseNilObjectException
3. ClaimDoctorReviewWindow.ClaimDoctorReviewWindow.ForceClose%%o<ClaimDoctorReviewWindow.ClaimDoctorReviewWindow>
4. ClaimDoctorReviewWindow.ClaimDoctorReviewWindow.SmsgGetItemizedBillLineItems_ResponseReceived%%o<ClaimDoctorReviewWindow.ClaimDoctorReviewWindow>o<M_REST.RESTMessageSurrogate_MTC>o<M_REST.RESTMessage_MTC>yi8x
5. Delegate.IM_Invoke%%o<TTsDiff.TextDiffProcessor>&s&s&b&o<HighlightDefinition>
6. AddHandler.Stub.6%%o<M_REST.RESTMessage_MTC>yi8x
7. M_REST.RESTMessageSurrogate_MTC.RaiseResponseReceived%%o<M_REST.RESTMessageSurrogate_MTC>o<M_REST.RESTMessage_MTC>yi8x
8. M_REST.RESTMessage_MTC.Event_PageReceived%%o<M_REST.RESTMessage_MTC>yi8o<Xojo.Core.MemoryBlock>
9. HTTPSocket_SetValidateCertificates
10. RandomInt
11. HTTPSocket_SetValidateCertificates

h1. Diagnostic Information



| Version | v2019.1.2
| GitRev | a0d1f6649a657ccb42b38c2288a95cdd00e685af
| Environment | Production
| Server | XX.XX.XX.XX:8354
| OS | Windows
| User | @username (00)
| User Home | C:\\Users\\USERNAME~1
| Data Folder | C:\\Users\\USERNAME~1\\DOCUME~1\\Dragon
| Memory Used | 325,193,728
| Object Count | 61,257
| Transport Connected | Yes
| Transport Last Error | 0
| IP Address 0 | XX.XX.XX.XX
| IP Address 1 | XX.XX.XX.XX

h1. Open Windows


1. Submit Unhandled Exception
2. 303 - Physician Data Sheet
3. 1080 - Physician Data Sheet
4. 303 - Doctor Review
5. 1080 - Doctor Review
6. Dragon - Dragon - Doctor Work Queue
7. 1083579 - Doctor Review
8. 1083579 - Physician Data Sheet
9. 1084510 - Physician Data Sheet

-- by [~username]

Thanks @Kem Tekinay I did not know that — I wish I knew this 10,000 pastes ago!

This is also needed if the Exception occurs in a Thread, and App.UnhandledException gets called from a Thread (so you can’t show any UI without yet another ThreadAccessingUIException).

I intended to ask how you deal with Exceptions raised in Threads. “Timer” answers that :slight_smile:

But then you always “return true” from App.UnhandledException, right? So you don’t let the App “crash”, but always perform a “regular Quit” (called from your BugReporting dialog)?

Or would there be a way to show a “user report dialog” in App.UnhandledException (even if caused by a Thread), and still “return false” (in order to let the App crash - if the user wants it)?

Doing this from memory, but we return true. The version of the User Report window that is opened is modal in that case and forces a quit when it’s done. And you’re right about keeping it out of the thread.

It’s just that using a Timer (and returning true) may cause some other code to be executed (until the Timer gets a chance to execute)… so if we want to prevent that - how to do that…? I don’t think there is some “CallThisMethodAlwaysOnMainThread” (and “do-it-right-now”, even if we’re currently called in a Thread-Context) in Xojo.

These are good points.

First, I haven’t tested to see if App.UnhandledException runs within the context of the Thread that raised the exception. I suspect it doesn’t, i.e., it always runs on the main thread, but would have to test.

The only way other code would execute is if it’s already running in a Thread or there is another Timer that starts before the exception handler Timer executes. You can deal with the latter by subclassing Timer and making sure it only runs if a flag is set. Dealing with the former would be trickier, and I can’t think of a good way offhand other than having your Thread code check that flag as it’s running.

If App.UnhandledException always runs on the main thread anyway, you can avoid the Timer by setting a flag within that event. When the event starts, it would check that flag and, if true, quit immediately or return false (hard crash). Otherwise, it would set the flag to true and proceed with the exception handling. The point is, if the exception handler raises another exception, you’re cooked anyway and might as well quit immediately.

(That may actually be how we did it, but I haven’t looked at that code in a while.)

I write the stack to the user’s logfile in the App.UnhandledException handler, and ask them to send it to me. Every line in the logfile is timestamped, too.

You are correct. It does not run within the context of the “crashed” Thread.

I’d say this depends on the kind of App, Task and possible dangers of a continuation in the specific situation.

Both macOS and Windows?
(I can‘t test this right now, but have the suspicion that Windows might be different…)

[quote=423036:@Jürg Otter]Both macOS and Windows?
(I can‘t test this right now, but have the suspicion that Windows might be different…)[/quote]
Many things would break if UnhandledException fired on anything but the main thread.

Yes. I catch App.UnhandledException’s also from Threads on Win and Mac and there’s no speacial handling just because “it came from a thread”. :slight_smile:

Right - thanks. I’ve also double-checked and can confirm that it’s safe to access UI in App.UnhandledException (as it’s called on the Main Thread on macOS and Windows - hopefully Linux, too).

Speaking of Unhandled Exceptions - be aware that they are kind of broken (or not working as expected) in Modal Dialogs…!
<https://xojo.com/issue/54796> - UnhandledExceptions in Modal Dialogs are not properly handled (leaving application in weird state)

And it seems that ExceptionHandling in Xojo is not in a good shape at all… there are quite some other verified “Unhandled Exception” related Feedback cases:
<https://xojo.com/issue/8646> - [IDESubmitted] Unhandled exceptions in modal dialogs are ignored
<https://xojo.com/issue/52346> - Unhandled exception inside Thread in Console app is ignored in Win32 builds
<https://xojo.com/issue/52133> - Unhandled exceptions are not caught when raised in a thread on Raspberry Pi console application
<https://xojo.com/issue/46480> - app.UnhandledException not called for all exceptions in threads in 64bit
<https://xojo.com/issue/15707> - The app’s “UnhandledException” event fails to fire when app opens a window programmatically with App property Appearance > DefaultWindow set to “None”.

[quote=423060:@Jürg Otter]Right - thanks. I’ve also double-checked and can confirm that it’s safe to access UI in App.UnhandledException (as it’s called on the Main Thread on macOS and Windows - hopefully Linux, too).

Speaking of Unhandled Exceptions - be aware that they are kind of broken (or not working as expected) in Modal Dialogs…!
<https://xojo.com/issue/54796> - UnhandledExceptions in Modal Dialogs are not properly handled (leaving application in weird state)

And it seems that ExceptionHandling in Xojo is not in a good shape at all… there are quite some other verified “Unhandled Exception” related Feedback cases:
<https://xojo.com/issue/8646> - [IDESubmitted] Unhandled exceptions in modal dialogs are ignored
<https://xojo.com/issue/52346> - Unhandled exception inside Thread in Console app is ignored in Win32 builds
<https://xojo.com/issue/52133> - Unhandled exceptions are not caught when raised in a thread on Raspberry Pi console application
<https://xojo.com/issue/46480> - app.UnhandledException not called for all exceptions in threads in 64bit
<https://xojo.com/issue/15707> - The app’s “UnhandledException” event fails to fire when app opens a window programmatically with App property Appearance > DefaultWindow set to “None”.[/quote]
Thanks for the list. We will take a look at these for r2. I don’t know how many we will be able to fix for r2 and some are clearly more important than others.

Hi Geoff
I recently logged a case related to exceptions not working. Not sure if it is covered by any of the cases already listed but it is one that should be fixed. Unfortunately, I don’t have access to Feedback at the moment so cannot tell you the case number but if you can search for cases logged by me you should be able to find it.

[quote=447277:@Kevin Gale]Hi Geoff
I recently logged a case related to exceptions not working. Not sure if it is covered by any of the cases already listed but it is one that should be fixed. Unfortunately, I don’t have access to Feedback at the moment so cannot tell you the case number but if you can search for cases logged by me you should be able to find it.[/quote]
Found it. <https://xojo.com/issue/56181>

We will take a look at it.

[quote=447338:@Geoff Perlman]Found it. <https://xojo.com/issue/56181>

We will take a look at it.[/quote]
Thanks.