%New error handling
Hi,
On a persistent class, I have defined an %OnNew method that validate some properties with appropriate status code for each kind of error.
Question is: how do you catch the specific error when %New is called on this class?
Surrounding %New method with a try-catch not seems to work.
Thanks
The error should be in the %objlasterror variable. You would have to check: if %New() returned a new instance, if not then check the value of %objlasterror. Then perform any error handling you'd like to do.
try/catch doesn't work because %New() doesn't throw any exceptions.
Thanks a lot Warlin!
I also found the documentation on that subject: %Status Error Processing
Interesting point Jenna. Thanks.
I'll try that!
While this is certainly possible, you'd be breaking the "contract". %OnNew() is expected to return a %Status that will be handled by %New(). This means the exception will be thrown by %OnNew() but %New() won't care about it and still return an object (unless something else prevents it from doing so).
I've changed my recommendation on this a little. Return the result of %ValidateObject() as the final argument, but don't return that status as the return value of the method. That way, if there are any required properties, and the call to %New() doesn't supply them, %OnNew() still works. Here's the updated example:
The proper way to do this would be
if the %OnNew is going to error you should throw an exception- If you did this, the thrown exception should be caught by your try/catch block that calls the %New() method. Then in the catch block you can examine either %objlasterror or perhaps some specific error variable you create for your purposes.
%OnNew() must return a %Status to %New(). But the code that calls %New() also needs the %Status. I think a "best practice" is simply to add an Output %Status argument to %OnNew() that will therefore be returned to %New(). So the %Status is being returned using return (for %New()) and by using a pass-by-reference argument (for the code that calls %New()).
Hi Blaise,
You can pass %OnNew expection to %New with this code snippet :
Now when you call the new method :
USER>set test = ##class(Test.PersitenceTest).%New()
If $isobject($get(newerror))=1 Throw newerror
^
<THROW>%Construct+9^Test.PersitenceTest.1 *%Exception.StatusException ERROR #5659: Property 'Test.PersitenceTest::mandatory(10@Test.PersitenceTest,ID=)' required
Now you can catch you %OnNew expection anywhere :