I’ve had some unexpected exceptions happening lately on my major project, and am hoping that someone has suggestions for how they might be possible. (These exceptions are in the built app, not when running in the IDE, so I can’t reproduce them.)
Here’s a typical code snippet, the user is getting a NilObjectException where Erln=2. The listbox is a control on a window, this code is called after the window opens. The Erln values are just to help identify where errors are happening.
The only thing that could go nil is the listbox, right? Since the error doesn’t happen on the first line, then ChooseListbox should still exist on the second line. What could make it go nil? The window closing in the middle of this code executing?
Exception Err As RuntimeException
If Err IsA EndException Or Err IsA ThreadEndException Then
Raise err //Re-raise the exception
End If
ReportTheBug (CurrentMethodName, Erln)
One way to identify what is wrong is to use a try/catch block that handle any exception. When such an exception occurs, display the exception error number, the message, variables contents etc. Send those values to the Debug Log.
One thing I find confusing in your code is if, for whatever reason, LastColumnIndex returns 0, the loop won’t execute at all. In this case, if the exception occurs after the loop (if there’s more in the actual code), Erln would also equal 2. I’d suggest adding Erln=6 after the End If, in general.
Now, for the actual issue, it’s weird, indeed. Could it be a timing issue, where your window is being closed between Erln=1 and Erln=2, from another place?
(I’d hardly expect that, but it’s my most logical answer)
Yes, probably so the order of opening and creation of controls is important (but out of your hands). That’s why almost alwyas you want to use the events of the control itself and use “Me.” or in case of subclass “Self.” to refer to the object.
We created a super for Window that starts a Timer in the Open event with a Period = 1. That raises an AfterOpen event where a subclass can set up controls like this knowing that the Window has been fully formed.
One thing to try before changing any code is to open and close the Window as fast as you can. That exposed similar issues for us.
Other than the lack of a try/catch block, that’s exactly what I’m doing. the Exception Err as Runtime Exception should be catching any exceptions. If the try/catch is essential, then I’d have to put try/catch blocks around every few lines of code everywhere in 600,000+ lines of code, which just isn’t feasible…
Try…Catch is the correct way to catch for exceptions you are ready to handle.
All other exceptions should bubble to the App.UnhandledException event, so that they may be reported to you. You should always exit your application when an unhandled exception occurs, as you don’t know just how messed up the state has become.
Advice suggesting you catch all exceptions at the bottom of every method is bad advice, and makes debugging things intelligently more difficult.
I’m hesitant to link the documentation, because again, it’s a really bad way to handle errors. But that’s what an exception statement does. It’s like a try…catch for the whole method.
There isn’t anything in the code other than what I posted, but I think your question exposed the true problem:
This is an API 1 app, but .LastColumnIndex is an API 1 property, while .ColumnCount is an API 2 property. So if .ColumnCount=0, then .LastColumnIndex would be -1, which makes ChooseListbox.Column(-1) nil.
You’re right! The hard part is there are about 600,000 lines of code, and many were written long before I knew better ways to do things… So for now anyway, it’s triage & rewrite as the bugs arise… Thank you!