fbpx
× Visual Objects

Please use this forum to post questions about Visual Objects and Vulcan.NET

Suggestions for conversion VO programs using VO GUI classes

  • Arne Ortlinghaus
  • Arne Ortlinghaus's Avatar Topic Author
  • Away
More
1 year 7 months ago #1 by Arne Ortlinghaus
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

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #2 by Wolfgang Riedmann
Replied by Wolfgang Riedmann on topic 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

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #3 by Otto Christiaanse
Replied by Otto Christiaanse on topic 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.

Please Log in or Create an account to join the conversation.

  • Arne Ortlinghaus
  • Arne Ortlinghaus's Avatar Topic Author
  • Away
More
1 year 7 months ago #4 by Arne Ortlinghaus
Hi Otto,
can you give some more information about what you are using?
Arne

Please Log in or Create an account to join the conversation.

  • Arne Ortlinghaus
  • Arne Ortlinghaus's Avatar Topic Author
  • Away
More
1 year 7 months ago #5 by Arne Ortlinghaus
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.

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #6 by Wolfgang Riedmann
Replied by Wolfgang Riedmann on topic 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

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #7 by Chris Pyrgas
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

XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

  • Arne Ortlinghaus
  • Arne Ortlinghaus's Avatar Topic Author
  • Away
More
1 year 7 months ago #8 by Arne Ortlinghaus
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

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #9 by Wolfgang Riedmann
Replied by Wolfgang Riedmann on topic 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

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #10 by Chris Pyrgas
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!

XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #11 by Paul Piko
Hi guys,

I'll come out of lurker mode ;)

Years ago when I did conference sessions on exception handling I suggested looking at this for ideas: C# Exception Handler . Of course it is not just for C#, and can be applied to any .NET language.

And don't forget to do something about any exceptions that aren't explicitly handled. Put these into your startup code as required:
  • AppDomain.UnhandledException= Notification of uncaught exceptions
  • Application.ThreadException= Triggered by exceptions that occur in Windows Forms threads; by default doesn’t trigger UnhandledException
  • Application.DispatcherUnhandledException= Triggered by exceptions occurring in WPF UI

E.g.

In XAML
<Application x:Class="ExceptionExampleWPF.App"
xmlns=" schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x=" schemas.microsoft.com/winfx/2006/xaml "
DispatcherUnhandledException="MyDispatcherUnhandledExceptionLogger"
StartupUri="Window1.xaml">
</Application>

In code
PROTECTED METHOD OnStartup(e AS StartupEventArgs) AS VOID
// Vulcan
Application.Current:DispatcherUnhandledException += ;
DispatcherUnhandledExceptionEventHandler{SELF,;
@MyDispatcherUnhandledExceptionLogger()}
SUPER:OnStartUp(e)
RETURN

Regards,
Paul

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #12 by Wolfgang Riedmann
Replied by Wolfgang Riedmann on topic Suggestions for conversion VO programs using VO GUI classes
Hi Chris,

thank you very much!

Wolfgang

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #13 by Wolfgang Riedmann
Replied by Wolfgang Riedmann on topic Suggestions for conversion VO programs using VO GUI classes
Hi Paul,

your contribution is very welcome! It's a long time I have read something from you, and I'm really happy that you are here.
The Exception handler link is very interesting, thank you!

Wolfgang

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #14 by Nick Friend
Hi Chris,

We use something like this for error logging in conjunction with Log4Net. I'd recommend this to everyone... very simple to implement and use and very flexible.

Nick

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #15 by Chris Pyrgas
That's very nice hearing from you Paul!
It's been a while, hope you're doing well and thanks for contributing!

Chris

XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #16 by Chris Pyrgas
Hi Nick,

Thanks for the pointer about Log4Net! But what did you mean you use in conjunction with it? I think you meant Paul's code?

Chris

XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #17 by Nick Friend
Hi Chris,

In our base classes we have some common error logging code which receives the Exception object from the Catch, and does the loop through the InnerExceptions as you showed, then the output can get logged via Log4Net.

Very simple and gives good clear log info for clearing up errors detected at runtime (never happens of course), or just for general logging to see what the program is doing.

Nick

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago - 1 year 7 months ago #18 by Otto Christiaanse
Replied by Otto Christiaanse on topic Suggestions for conversion VO programs using VO GUI classes

Arne Ortlinghaus wrote: Hi Otto,
can you give some more information about what you are using?
Arne


Hi Arne,
yes I can.

I use PostSharp, which implements Aspect Oriented Programming.
Your methods focus on the key businesslogic, and all default other kind BS is seperated and backed into Aspects.
If all of your methods must have some kind of exception handling, you define it in one place, and point the methods you want to augment with that behaviour.

In the following example an exception is thrown in the method MyBuggyMethod, caught in the aspect MyOnExceptionAspect, written to the console and ignored (by changing the FlowBehavior to FlowBehavior.Return). You can add logic to log the error, decide whether this exception can be ignored etc, and continue.

Aspects can be used for logging, checking parameters of methods etc.
You can mix XSharp and CSharp in creating Aspects or using them without problem.

I post here the essential pieces of the code:
BEGIN NAMESPACE Aspects

    /// <summary>
    /// The MyOnExceptionAspect class.
    /// </summary>
    [PSerializable];
    public class MyOnExceptionAspect INHERIT OnExceptionAspect
    
        override public METHOD OnException(args AS MethodExecutionArgs) AS VOID STRICT
        
            Console.WriteLine(i"From within the XSharp OnExceptionAspect: {args.Exception.Message}")
            args:FlowBehavior := FlowBehavior.Return
            return
    END CLASS
END NAMESPACE
BEGIN NAMESPACE PostSharpTest
    public CLASS Test

            [MyOnExceptionAspect];
            METHOD MyBuggyMethod(mustThrow as LOGIC) as void strict
                IF mustThrow
                    throw Exception{"I had to throw an exception"}
                ENDIF
            RETURN

    END CLASS	
END NAMESPACE // PostSharpTest
    FUNCTION Start() AS VOID
        Console.WriteLine("Hello World!")
        LOCAL t AS Test
        t := Test{}
        Console.WriteLine("before the buggy method")
        t:MyBuggyMethod(true)
        Console.WriteLine("after the buggy method")

        Console.WriteLine("Press any key to continue...")

        Console.ReadKey()
    RETURN

The output in the console is:
before the buggy method
From within the XSharp OnExceptionAspect: I had to throw an exception
after the buggy method
Last edit: 1 year 7 months ago by Otto Christiaanse. Reason: markup

Please Log in or Create an account to join the conversation.

More
1 year 7 months ago #19 by Meinhard Schnoor
Hi guys!

Just my two cents...

You should definitely look into the exception handling block of Microsofts Enterprise Library!

Regards
Meinhard

Please Log in or Create an account to join the conversation.

  • Arne Ortlinghaus
  • Arne Ortlinghaus's Avatar Topic Author
  • Away
More
1 year 7 months ago #20 by Arne Ortlinghaus
Dieter Crispien 2 years ago proposed also installing a global error handler via AppDomain for all unhandled exceptions similar to the code below saying that this is only for exceptions that cannot be handled ordinarily by a correct error block.
I tested it with a simulated simple runtime error within the GUI classes. The message was output on the screen, but then the app crashed nevertheless.

In Start function after creating shellobject
AppDomain.CurrentDomain:UnhandledException += UnhandledExceptionEventHandler{ oWinShell , @WinShell.UnhandledException()}

PARTIAL CLASS WinShell

METHOD UnhandledException(sender AS OBJECT, e AS UnhandledExceptionEventArgs) AS VOID
LOCAL ex AS Exception

ex := (Exception)e:ExceptionObject

msgerror ("Unhandled exception in program " + errorobject2string(ex))
RETURN

END CLASS

Please Log in or Create an account to join the conversation.