(Updated: 2003.04.30 02:27:20 PM)
| |
This is some code that
Bob Wright wrote based on the original
Throw Exception topic posted by
Mike Helland.
See Bob's comments at the bottom of the page.
&& this code is based on that global throw function that
&& was on that fox wiki link you sent me. I hope you find this
&& interesting.
SET STEP ON
&& Main try block
TRY
&& this next method call is really interesting approach
&& Keeps responsibility of adding custom properties and augmenting
&& original exception properties to custom exceptions.
ThrowException(CREATEOBJECT("CustomerNotFoundException"))
&& this next example is just a simple string assign to exception thrown
*!* ThrowException(CREATEOBJECT("SimpleStringException"))
CATCH TO oE
SET STEP ON
?""
ENDTRY
&& End of main try block
DEFINE CLASS SimpleStringException as MyCustomException
FUNCTION SetExceptionProperties(oException as Exception) as VOID
&& Assign user defined values to original exception
oException.Message = "User Message goes here"
oException.UserValue = This
ENDFUNC
ENDDEFINE
&& Derived from MyCustomException
&& A little more complex Custom exception
DEFINE CLASS CustomerNotFoundException as MyCustomException
&& Overriding an abstract method
FUNCTION SetExceptionProperties(oException as Exception) as VOID
&& Assign user defined values to original exception
oException.Message = "Customer not found"
oException.UserValue = This && Put Reference to UD Exception in userValue property reference.
This.AddUserdefinedProperties(oException)
ENDFUNC
&& Additional excption method code.
FUNCTION AddUserdefinedProperties(oException as Exception) as VOID
&& Add user defined properties to original exception
oException.AddProperty("CustomExceptionProperty1", "Raised by custom Exception")
oException.AddProperty("CustomExceptionProperty2", "What everelse")
THIS.DoWhateverElse()
ENDFUNC
FUNCTION DoWhateverElse()
&& Not really practical use. Just example that one could use endless
&& Method call to suit ones needs
MESSAGEBOX("Nothing to add")
ENDFUNC
ENDDEFINE
&& Base class for customExceptions
DEFINE CLASS MyCustomException as Exception
FUNCTION SetExceptionProperties(oException as Exception) as VOID
ENDFUNC
ENDDEFINE
&& Global Exception Function
FUNCTION ThrowException(vException as Variant)
LOCAL sClassString
TRY
sClassString = GetClassHierarchy(vException)
THROW
&& check to see if exception "is a" MyCustomException
&& CATCH TO oCaughtException WHEN "MYCUSTOMEXCEPTION" $ UPPER(sClassString)
CATCH TO oCaughtException WHEN InClassHierarchy(vException, "MYCUSTOMEXCEPTION")
vException.SetExceptionProperties(oCaughtException)
THROW
ENDTRY
ENDFUNC
FUNCTION InClassHierarchy(oException as Exception, sClassName as String ) as Boolean
LOCAL ARRAY aClassArray(1) && Array of class hierarchy
LOCAL ReturnVal as Boolean, nElement as Number
IF TYPE("oException") = "O"
ACLASS(aClassArray, oException)
nElement = ASCAN(aClassArray,sClassName,1,-1,-1)
ReturnVal = nElement > 0
ENDIF
RETURN ReturnVal
ENDFUNC
&& Function to get class hierarchy
FUNCTION GetClassHierarchy(oException as Exception) as String
LOCAL ARRAY aClassArray(1) && Array of class hierarchy
LOCAL sClassString,; && String of class hierarchy
nClassCount,; && Number of classes in hierarchy
I
sClassString = ""
IF TYPE("oException") = "O"
nClassCount = ACLASS(aClassArray, oException)
FOR I = 1 TO nClassCount
sClassString = sClassString + "'" + aClassArray(I) + "',"
ENDFOR
ENDIF
RETURN sClassString
ENDFUNC
[2003.04.26]
When issuing a statement such as this: "THROW
Create Object('MyCustomException')" Fox will throw a "User Defined" Exception. I thought this was misleading in a sense, it really raises a VFP Exception object and stores a reference to the object of type "
MyCustomException" in the property
UserValue of the VFP Exception object. Well what if the
MyCustomException that I raised had responsibilities?? What if a higer error handler needed to be informed of the responsiblities this exception object just performed?
Well with Mike's idea with a global
Throw Exception() function, one could kind of mask this desired behavior. If I where to Catch an Exception only if the object THROWN "is a
MyCustomException" I could run all my custom code with one line of code in Mike's
Throw Exception() funtion for any object derived from type "
MyCustomException". So now if I were create a class "
CustomerNotFound as
MyCustomException" with Mike's approach when I throw this object it will be caught as well.
Since
MyCustomException has an abstract method with a signiture of
SetExceptionProperties(vException as variant) as void, one could pass the original Exception to the object derived from "
MyCustomException" augment the VFP Exception to look like what ever you want and escalate the original exception. It won't escalate the responsibilities (Methods) that "
MyCustomException" has, but you can make the VFP Exception kindof look like it.
This is just a idea that I had one night. I know there is a little bit of overhead with this approach but I think this encapsulates the responsiblities to the userdefined object and allows one to alter the original exception object to look like something else. Any thoughts or constructive criticism are welcome.
Bob Wright
It's great to see that someone was able to incorporate custom Exception objects - in fact, before I tried setting all the properties on the caught exception in Throw Exception I tried this instead but it unfortunately ignored the variable re-reference:
Function ThrowException(oCustomException)
Local oExp
Try
Throw
Catch To oExp
oExp = oCustomException
Throw
EndTry
- but I think the 90% use case is covered by Throw Exception; granted, you'd want to be using constants for the message names making them easily adjustable and compareable. Unless anyone can think of an ultra spiffy advantage to having an exception object with method's on it? -- Mike Helland
Category Code Samples Category Error Handling