THROWING and CATCHING from methods

Posted by Jeff Ledbetter on 10-Apr-2008 14:44

Does anyone have an example of catching an error thrown from a method? I wouldn't think that this would be difficult, but I cannot catch the error in my calling procedure. The help examples aren't very helpful at all as they are all procedural based.

I've whittled my example down to this. What am I missing/doing wrong? Is the DO block in the method even necessary?

class:

USING Progress.Lang.*.

CLASS SomeClass:

METHOD PUBLIC VOID someMethod (myInput AS CHARACTER):

DO ON ERROR UNDO:

IF myInput <> "jeff" THEN

UNDO, THROW NEW Progress.Lang.AppError("You are not Jeff!").

END.

END METHOD.

END CLASS.

caller:

DEFINE VARIABLE someclass AS SomeClass.

someclass = NEW SomeClass().

DO ON ERROR UNDO:

someclass:SomeMethod("Bob").

CATCH e AS Progress.Lang.AppError:

MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX.

DELETE OBJECT e.

END CATCH.

END.

All Replies

Posted by Jeff Ledbetter on 11-Apr-2008 11:43

Nevermind.

Posted by Thomas Mercer-Hursh on 11-Apr-2008 11:57

Care to enlighten us on your insight?

Posted by rbf on 11-Apr-2008 14:18

The problem is in the following statement:

But in that case the error text is on the ReturnValue property of the error object and not as a message.

I am not sure why your original syntax does not work, from the documentation I would expect it to work as well.

BTW you don't need any of the DO ON ERROR UNDO blocks as you are using a catch block.

Posted by Thomas Mercer-Hursh on 11-Apr-2008 14:31

Per the ABL reference, it looks like the method could take the CATCH block without the DO, but if one uses a DO, then it must either have TRANSACTION or ON ERROR, UNDO.

Posted by Jeff Ledbetter on 11-Apr-2008 14:45

This gives me the expected results:

Procedure:

DEFINE VARIABLE someclass AS SomeClass.

someclass = NEW SomeClass().

DO ON ERROR UNDO:

someclass:SomeMethod("Bob").

CATCH e AS Progress.Lang.AppError:

MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX ERROR.

DELETE OBJECT e.

END CATCH.

END.

Class:

USING Progress.Lang.*.

CLASS SomeClass:

METHOD PUBLIC VOID someMethod (myInput AS CHARACTER):

IF myInput <> "jeff" THEN

UNDO, THROW NEW Progress.Lang.AppError("You are not Jeff!",1).

CATCH e AS Progress.Lang.AppError:

UNDO, THROW e.

END CATCH.

END METHOD.

END CLASS.

It seems since the method is an enclosing block, then I have to catch it in the method and then re-throw it.

Posted by Thomas Mercer-Hursh on 11-Apr-2008 14:56

So, if you omit the CATCH within the method, what happens?

Is that USING necessary?

Posted by rbf on 11-Apr-2008 14:56

This is sufficient:

Procedure:

DEFINE VARIABLE someclass AS someClass.

someclass = NEW someClass().

someclass:SomeMethod("Bob").

CATCH e AS Progress.Lang.AppError:

MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX.

DELETE OBJECT e.

END CATCH.

Class:

CLASS someClass:

METHOD PUBLIC VOID someMethod (myInput AS CHARACTER):

IF myInput <> "jeff" THEN

/* RETURN ERROR "You are not Jeff!". */

UNDO, THROW NEW Progress.Lang.AppError("You are not Jeff!",0).

END METHOD.

END CLASS.

Posted by Jeff Ledbetter on 11-Apr-2008 15:05

Well, taking the CATCH from the method still produces the results I wanted. I thought that it was working differently this morning. As Peter mentioned (it didn't sink in the first time), perhaps it was the fact that I was not passing two parameters to the AppError constructor.

No, the USING is not necessary since I specified the full package for AppError.

So, the new class is simply:

CLASS SomeClass:

METHOD PUBLIC VOID someMethod (myInput AS CHARACTER):

IF myInput <> "jeff" THEN

UNDO, THROW NEW Progress.Lang.AppError("Damnit, you are not Jeff!",1).

END METHOD.

END CLASS.

This thread is closed