routinelevel.i

Posted by Admin on 13-Apr-2011 07:57

/** ------------------------------------------------------------------------

    File        : routinelevel.i

    Purpose     : Toggles all ROUTINE-LEVEL ON ERROR UNDO, THROW statements on or off. 

                  Use an include in leiu of a switch on the AVM command line (since that

                  doesn't exist).

    @author pjudge

    Created     : Fri Jan 21 14:02:16 EST 2011

    Notes       : * Default is to use ROUTINE-LEVEL

  ---------------------------------------------------------------------- */

/* ********************  Preprocessor Definitions  ******************** */

&if defined(USE-ROUTINE-LEVEL) eq 0 &then

    &global-define USE-ROUTINE-LEVEL false

&endif

&if "{&USE-ROUTINE-LEVEL}" eq "true" &then

routine-level on error undo, throw.

&endif

Can someone explain me please the purpose of this include?

It's included everywhere. The comment say "* Default is to use ROUTINE-LEVEL" but in fact, the default, when the preprocessor variable USE-ROUTINE-LEVEL is not set, is false, not true.

In fact no class in the AutoEdge/OERI sample code uses strcutured error handling because of that. Is that desired? I hope not!!!

All Replies

Posted by jmls on 13-Apr-2011 08:01

you have way, way too much time on your hands ..

Posted by Admin on 13-Apr-2011 08:03

Well, I've reserved today to get AETF running, and I planned to look into PSC's Collection implementations and some other useful stuff.

Some bit's look promising...

Posted by Peter Judge on 13-Apr-2011 08:09

mikefe wrote:

/** ------------------------------------------------------------------------
    File        : routinelevel.i
    Purpose     : Toggles all ROUTINE-LEVEL ON ERROR UNDO, THROW statements on or off. 
                  Use an include in leiu of a switch on the AVM command line (since that
                  doesn't exist).
    @author pjudge
    Created     : Fri Jan 21 14:02:16 EST 2011
    Notes       : * Default is to use ROUTINE-LEVEL
  ---------------------------------------------------------------------- */

/* ********************  Preprocessor Definitions  ******************** */
&if defined(USE-ROUTINE-LEVEL) eq 0 &then
    &global-define USE-ROUTINE-LEVEL false
&endif

&if "{&USE-ROUTINE-LEVEL}" eq "true" &then
routine-level on error undo, throw.
&endif



Can someone explain me please the purpose of this include?



It's included everywhere. The comment say "* Default is to use ROUTINE-LEVEL" but in fact, the default, when the preprocessor variable USE-ROUTINE-LEVEL is not set, is false, not true.



In fact no class in the AutoEdge/OERI sample code uses strcutured error handling because of that. Is that desired? I hope not!!!


I dislike having to use this include, and I wrote the dam thing 

Its purpose is to make it easy to turn all routine-level handling on or off globally - and I have found no other way of doing this, short of search and replace R-L with /* R-L */ (if you know what I mean). There are time where I really really want to see where an ABL error originates and debug that, and when ROUTINE-LEVEL is on, I only catch the error "up top" or at or near the .P that started everything, and this makes debugging impossible (since I'm not at the class where the error originated) . I would *love* an alternative to my approach.

The fact that it says 'false' by default is a bug - it should be true (and will be in the next drop).

-- peter

Posted by Admin on 13-Apr-2011 08:15

There are time where I really really want to see where an ABL error originates and debug that, and when ROUTINE-LEVEL is on,

We must have made different debugging experiences. For me the ROUTINE-LEVEL ON ERROR UNDO, THROW. makes debugging way much easier. And unit-testing as well. We have default routines to show (and log) error messages including their stack.

The fact that it says 'false' by default is a bug - it should be true (and will be in the next drop).

When's that expected??? :-)

Posted by Peter Judge on 13-Apr-2011 08:26

There are time where I really really want to see where an ABL error

originates and debug that, and when ROUTINE-LEVEL is on,

We must have made different debugging experiences. For me the ROUTINE-LEVEL

ON ERROR UNDO, THROW. makes debugging way much easier. And unit-testing as

well. We have default routines to show (and log) error messages including

their stack.

Don't get me wrong, I like ROUTINE-LEVEL immensely, and agree with all of what you say. But if I want to debug the app using the debugger from the point at which the error happened, I need to not use ROUTINE-LEVEL, since at the point at which I know about the error I am in a completely different compile unit: so given start.p

Start.p

oAppObject = ServiceManager:StartService('myapp').

catch e as ApplicationError:

e:ShowMessage().

end catch.

If an error happens somewhere in the oAppObject class, and I have ROUTINE-LEVEL, I will only know about the ApplicationError in start.p and NOT the class in which it occurs.

The fact that it says 'false' by default is a bug - it should be true (and

will be in the next drop).

When's that expected???

Soon? Jokes aside, it should be next week. Got to implement the CLIENT-PRINCIPAL and some other misc updates first ...

-- peter

Posted by Håvard Danielsen on 13-Apr-2011 12:25

One important advice in this context is to always use -errorstack if you use routine-level undo and make sure the error handler (ShowMessage in this case) shows :CallStack (which I believe it does?).

Posted by Peter Judge on 13-Apr-2011 15:11

hdaniels wrote:

One important advice in this context is to always use -errorstack if you use routine-level undo and make sure the error handler (ShowMessage in this case) shows :CallStack (which I believe it does?).

I should clarify: I want to be able to press 'Debug' on the ABL stack trace and pick up from where the error was raised (especially in the case of unexpected ABL errors). If I have ROUTINE-LEVEL then I cannot do that, since the pace I see the emssage box/stack trace is typically far removed from the point at which the error was raised. -errorstack and friends give me lots of information but I cannot unwind the stack in the debugger and go back to the point at which the error was raised from the point at which I caught it.

-- peter

Posted by Admin on 13-Apr-2011 15:12

Don't get me wrong, I like ROUTINE-LEVEL immensely, and agree with all of what you say. But if I want to debug the app using the debugger from the point at which the error happened, I need to not use ROUTINE-LEVEL, since at the point at which I know about the error I am in a completely different compile unit: so given start.p

Ok, but the combination of using Assert's with Exceptions (Like it) to test the validity of passed in parameters (and those errors should be thrown to the caller of that method and not just from the Assert method to the actual method) and not using ROUTINE-LEVEL ON ERROR UNDO, THROW. sounds like a night mare combination.

Plus, the fact that you just deployed (in 1.0.3) the whole code without ROUTINE-LEVEL ON ERROR UNDO, THROW shows how dangerous this is. I'd quickly rethink the debugging strategy :-)

Soon?  Jokes aside, it should be next week. Got to implement the CLIENT-PRINCIPAL and some other misc updates first ...

Uh man. I hope it's going to be faster than the last "soon" that was promised for an AutoEdge update.

Posted by Admin on 13-Apr-2011 15:14

I should clarify: I want to be able to press 'Debug' on the ABL stack trace and pick up from where the error was raised (especially in the case of unexpected ABL errors). If I have ROUTINE-LEVEL then I cannot do that, since the pace I see the emssage box/stack trace is typically far removed from the point at which the error was raised. -errorstack and friends give me lots of information but I cannot unwind the stack in the debugger and go back to the point at which the error was raised from the point at which I caught it.

Did you already discuss that with the guys next door (aka the debugger developers)?

Posted by Peter Judge on 13-Apr-2011 15:21

Did you already discuss that with the guys next door (aka the debugger

developers)?

I have discovered (thanks Matt B) - and am feeling very sheepish right about now, I should add - that this is already possible (in 10.2B04); in the breakpoints view, you can r-click to add a break point; in it is a dialogue allowing me to specify a raise-on-error breakpoint. Ahem. Just like in the 'old' debugger.

Ok, but the combination of using Assert's with Exceptions (Like it) to test

the validity of passed in parameters (and those errors should be thrown to

the caller of that method and not just from the Assert method to the actual

method) and not using ROUTINE-LEVEL ON ERROR UNDO, THROW. sounds like a night

mare combination.

The above means that I can replace the include with a real ROUTINE-LEVEL statement. And still be able to use the debugger as I wish. I plan to remove the include and revert to the statement.

Plus, the fact that you just deployed (in 1.0.3) the whole code without

ROUTINE-LEVEL ON ERROR UNDO, THROW shows how dangerous this is. I'd quickly

rethink the debugging strategy

Agree and I would much rather use a clear ROUTINE-LEVEL ON ERROR UNDO, THROW statement in each compilation unit/class/procedure.

Do you use ROUTINE-LEVEL in all classes/procedures etc? If not, how do you suggest this should be approached (given the ABL as it is today?)

-- peter

Posted by Admin on 13-Apr-2011 15:48

I have discovered (thanks Matt B) - and am feeling very sheepish right about now, I should add -  that this is already possible (in 10.2B04); in the breakpoints view, you can r-click to add a break point; in it is a dialogue allowing me to specify a raise-on-error breakpoint. Ahem. Just like in the 'old' debugger.

good news.And for those of use not receiving salary from PSC (anymore) service pack 4 is out just since a week or so. No need to feel sheepish...

Do you use ROUTINE-LEVEL in all classes/procedures etc? If not, how do you suggest this should be approached (given the ABL as it is today?)

In every new code that I write I use ROUTINE-LEVEL ON ERROR UNDO, THROW - with the exception of small additions to very old code.

I try to remember to add it to any block as well - but that's hard to remember always, hence the request for a BLOCK-LEVEL ON ERROR UNDO, THROW.

I wouldn't recommend anybody to globally use it with old/exisiting code. For instance, I wouldn't wanna be the first one to test how the ADM2 libraries and SmartObjects or Dynamics managers would behave when you add RLEOEUT. And I've seen tooo much code (coming from old TTY UI) where users are used to runtime messages rushing thru the message area during a long running report (putting a cup on the space bar to confirm them). Of course that code needs a rework, but with a massive addition of RLEOEUT the report would terminate at the first error....

Posted by Mike Ormerod on 22-Apr-2011 09:16

mikefe wrote:

Soon?  Jokes aside, it should be next week. Got to implement the CLIENT-PRINCIPAL and some other misc updates first ...

Uh man. I hope it's going to be faster than the last "soon" that was promised for an AutoEdge update.

Lets just say our goals shifted a couple of times as we went through the project!!  But hey, we got something published in the end, and I promise we'll be a lot more frequent from now on :-)

This thread is closed