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.
Nevermind.
Care to enlighten us on your insight?
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.
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.
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.
So, if you omit the CATCH within the method, what happens?
Is that USING necessary?
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.
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.