There are still many runtime errors hidden in our programs. They are sometimes quite difficult to detect, most of all the errors that are connected to events of the GUI classes.
In contrast to Windows Forms the GUI classes have not inserted much error handling treating Windows events, so many "simple" runtime errors remain unhandled and provoke heavy app crashes without readable error messages.
It is convenient to make the following steps:
- Recompile the VO classes with X#
- Insert error handling for the event methods you have overwritten like "Buttonclick", "Listboxselect", ...
Example from the calling part for the "Buttonclick"-event method
TRY // <<<<< Start of errorblock
if IsInstanceOf(oChild, #PushButton)
// force focus to button to update values
oChild:SetFocus() // AO TRUE)
if !self:__CommandFromEvent(oTempEvent)
self:ButtonClick(oTempEvent)
else
self:EventReturnValue := 1l
endif
else
self:ButtonClick(oTempEvent)
endif
// ---- Error handling using some error output messages as is convenient for your own programs
CATCH oError as Exception //X# AO 4/2017
local c :="ButtonClick Error ,... "
c += CRLF + Asstring(self) +" " + asstring(oEvt)
_CallClipfunc(#MsgErrorDB, {c, nil, oError})
END TRY
Arne
Suggestions for conversion VO programs using VO GUI classes
- ArneOrtlinghaus
- Posts: 412
- Joined: Tue Nov 10, 2015 7:48 am
- Location: Italy
Suggestions for conversion VO programs using VO GUI classes
Hi Arne,
I thought about something like this not only for the GUI classes, but also for my own classes.
Unfortunately in .NET it is not possible to use global error handlers, but IMHO a solution could be to use the preprocessor to insert error handling in every method of a library.
Or maybe the development team could give us a better idea? Error handling in legacy code is one of my greatest concerns....
Wolfgang
I thought about something like this not only for the GUI classes, but also for my own classes.
Unfortunately in .NET it is not possible to use global error handlers, but IMHO a solution could be to use the preprocessor to insert error handling in every method of a library.
Or maybe the development team could give us a better idea? Error handling in legacy code is one of my greatest concerns....
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Suggestions for conversion VO programs using VO GUI classes
One word: Postsharp. It works also with XSharp
Then you can decide whether you want to add it to a method or not.
Then you can decide whether you want to add it to a method or not.
- ArneOrtlinghaus
- Posts: 412
- Joined: Tue Nov 10, 2015 7:48 am
- Location: Italy
Suggestions for conversion VO programs using VO GUI classes
Hi Otto,
can you give some more information about what you are using?
Arne
can you give some more information about what you are using?
Arne
- ArneOrtlinghaus
- Posts: 412
- Joined: Tue Nov 10, 2015 7:48 am
- Location: Italy
Suggestions for conversion VO programs using VO GUI classes
Hi Wolfgang,
my experience is:
It needs at least one Try/Recover block to surround X# code without being interrrupted by Windows API functions. So Batch processes normally are not so critical because it is normally possible to have one Try/Recover block in the calling process. The GUI classes are much more problematic.
Example:
A button action is surrounded by a Try/Recover block.
But the error happens within a method triggered by a Windows event originally initiated by the button action.
Then this cannot be handled correctly by the Try/Recover, but needs another Try/Recover block inside or outside the event method. I have searched in our programs which event methods have been overwritten and I have found about 50 different methods used, but many of them hundreds of times. It is because of this that I have thought on changing the VO GUI classes. Each event method normally is called normally in one, two, three different places, not more.
my experience is:
It needs at least one Try/Recover block to surround X# code without being interrrupted by Windows API functions. So Batch processes normally are not so critical because it is normally possible to have one Try/Recover block in the calling process. The GUI classes are much more problematic.
Example:
A button action is surrounded by a Try/Recover block.
But the error happens within a method triggered by a Windows event originally initiated by the button action.
Then this cannot be handled correctly by the Try/Recover, but needs another Try/Recover block inside or outside the event method. I have searched in our programs which event methods have been overwritten and I have found about 50 different methods used, but many of them hundreds of times. It is because of this that I have thought on changing the VO GUI classes. Each event method normally is called normally in one, two, three different places, not more.
Suggestions for conversion VO programs using VO GUI classes
Hi Arne,
unfortunately this is true also in nearly all of my programs: I have a lot of code in event handlers....
As I wrote: error handling is my biggest concern in this migration, and I hope Robert or Chris can give us an idea how to solve this.
Wolfgang
unfortunately this is true also in nearly all of my programs: I have a lot of code in event handlers....
As I wrote: error handling is my biggest concern in this migration, and I hope Robert or Chris can give us an idea how to solve this.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Suggestions for conversion VO programs using VO GUI classes
Hi Wolfgang (and all!),
Error handling of your VO apps should still work fine in .Net. Unless I am forgetting something else, the only thing in this area that will not work in x# (because it is not supported by the .Net runtime) is the ErrorBlock() functionality for registering a global error handler. But it is still possible to register a global error handler in a different way, by using a TRY..CATCH in your Start() function.
Of course you don't have the possibility this way to just ignore an exception and continue with execution of your app, is this what you are missing? If yes, then TRY...CTACH (or BEGIN SEQUENCE...RECOVER) statements must be added more locally, around blocks of code were you "expect" exceptions to happen. So this depends on your specific needs, what kind of exceptions do you handle through a global error handler in your VO apps?
Regarding GUI exceptions, based on Arne's suggestion, I got the idea of surrounding the Window:Dispatch() code with a TRY..CATCH statement, this should help trapping all related exceptions. I don't think it would have a measurable performance hit, but would be better to test it of course.
Chris
Error handling of your VO apps should still work fine in .Net. Unless I am forgetting something else, the only thing in this area that will not work in x# (because it is not supported by the .Net runtime) is the ErrorBlock() functionality for registering a global error handler. But it is still possible to register a global error handler in a different way, by using a TRY..CATCH in your Start() function.
Of course you don't have the possibility this way to just ignore an exception and continue with execution of your app, is this what you are missing? If yes, then TRY...CTACH (or BEGIN SEQUENCE...RECOVER) statements must be added more locally, around blocks of code were you "expect" exceptions to happen. So this depends on your specific needs, what kind of exceptions do you handle through a global error handler in your VO apps?
Regarding GUI exceptions, based on Arne's suggestion, I got the idea of surrounding the Window:Dispatch() code with a TRY..CATCH statement, this should help trapping all related exceptions. I don't think it would have a measurable performance hit, but would be better to test it of course.
Chris
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
- ArneOrtlinghaus
- Posts: 412
- Joined: Tue Nov 10, 2015 7:48 am
- Location: Italy
Suggestions for conversion VO programs using VO GUI classes
Hi Chris,
I tested already surrounding the start function with a try catch. But this way the errors generated within the GuI give no meaningful trace information and can give hard app crashes nevertheless.
Inserting error handling for the Windows dispatch method could be the solution. Probably there are some more places. The controls have another dispatch method for example.
Arne
I tested already surrounding the start function with a try catch. But this way the errors generated within the GuI give no meaningful trace information and can give hard app crashes nevertheless.
Inserting error handling for the Windows dispatch method could be the solution. Probably there are some more places. The controls have another dispatch method for example.
Arne
Suggestions for conversion VO programs using VO GUI classes
Hi Chris,
unfortunately I have the same experience as Arne: a central try-catch does not give meaningful traces. To have a meaningful error trace, the try-catch block must be in the entity where the error is occurring.
Wolfgang
unfortunately I have the same experience as Arne: a central try-catch does not give meaningful traces. To have a meaningful error trace, the try-catch block must be in the entity where the error is occurring.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Suggestions for conversion VO programs using VO GUI classes
Guys,
Here's some nice code that Robert sent me the other day and we are now injecting from the VO exporter tool to the Start() function of ported from VO apps. This should give meaningful enough error messages, of course you can modify it to get only the callstack or other info you need:
TRY
// app execution here
CATCH e AS Exception
LOCAL cMessage AS STRING
cMessage := e:Message
DO WHILE e:InnerException != NULL_OBJECT
e := e:InnerException
cMessage += CRLF+e:Message
ENDDO
ErrorBox{NIL, cMessage}:Show()
END TRY
Chris
ps. quite some drama in Le Mans as I'm writing this!
Here's some nice code that Robert sent me the other day and we are now injecting from the VO exporter tool to the Start() function of ported from VO apps. This should give meaningful enough error messages, of course you can modify it to get only the callstack or other info you need:
TRY
// app execution here
CATCH e AS Exception
LOCAL cMessage AS STRING
cMessage := e:Message
DO WHILE e:InnerException != NULL_OBJECT
e := e:InnerException
cMessage += CRLF+e:Message
ENDDO
ErrorBox{NIL, cMessage}:Show()
END TRY
Chris
ps. quite some drama in Le Mans as I'm writing this!
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu