Creating user-defined exception types
You can create your own user-defined exception types from
standard class user objects that inherit from Exception or RuntimeError
or that inherit from an existing user object deriving from Exception
or RuntimeError.
Inherit from Exception object type
Normally, user-defined exception types should inherit from
the Exception type or a descendant, since the RuntimeError type
is used to indicate system errors. These user-defined objects are
no different from any other nonvisual user object in the system.
They can contain events, functions, and instance variables.
This is useful, for example, in cases where a specific condition,
such as the failure of a business rule, might cause application
logic to fail. If you create a user-defined exception type to describe
such a condition and then catch and handle the exception appropriately,
you can prevent a runtime error.
Throwing exceptions
Exceptions can be thrown by the runtime engine to indicate
an error condition. If you want to signal a potential exception
condition manually, you must use the THROW statement.
Typically, the THROW statement is used
in conjunction with some user-defined exception type. Here is a
simple example of the use of the THROW statement:
1 |
Exception    le_ex<br>le_ex = create Exception<br>Throw le_ex<br>MessageBox ("Hmm", "We would never get here if" &   <br>   + "the exception variable was not instantiated") |
In this example, the code throws the instance of the exception le_ex.
The variable following the THROW reserved word
must point to a valid instance of the exception object that derives
from Throwable. If you attempt to throw an uninstantiated Exception
variable, a NullObjectError is thrown instead, indicating a null
object reference in this routine. That could only complicate the error
handling for your application.
Declaring exceptions thrown from functions
If you signal an exception with the THROW statement
inside a method script—and do not surround the statement
with a try-catch block that can deal with that type of exception—you
must also declare the exception as an exception type (or as a descendant
of an exception type) thrown by that method. However, you do not
need to declare that a method can throw runtime errors, since PowerBuilder
does that for you.
The prototype window in the Script view of most PowerBuilder
painters allows you to declare what user-defined exceptions, if
any, can be thrown by a function or a user-defined event. You can
drag and drop exception types from the System Tree or a Library
painter view to the Throws box in the prototype window, or you can
type in a comma-separated list of the exception types that the method
can throw.
Example
Example catching a user-defined exception
This code displays a user–defined error when an arccosine argument,
entered by the application user, is not in the required range. The
try-catch block calls a method, wf_acos,
that catches the system error and sets and throws the user-defined
error:
1 |
TRY   <br>   wf_acos() |
1 |
CATCH (uo_exception u_ex)   <br>   MessageBox("Out of Range", u_ex.GetMessage())<br>END TRY |
This code in the wf_acos method
catches the system error and sets and throws the user-defined error:
1 |
uo_exception lu_error<br>Double ld_num<br>ld_num = Double (sle_1.text)<br>TRY<br>   sle_2.text = string (acos (ld_num))<br>CATCH (runtimeerror er)   <br>   lu_error = Create uo_exception<br>   lu_error.SetMessage("Value must be between -1" &<br>      + "and 1")<br>   Throw lu_error<br>END TRY |
Integration with EAServer
If you declare exceptions on a method of a user object and
deploy the user object as a component to EAServer,
the exceptions are translated to IDL (CORBA) as part of the method
prototype. This means that PowerBuilder components in EAServer can be defined to throw
exceptions that can be handled by any type of EAServer client
application.
Other benefits for EAServer applications
Another benefit for component development is that you can
handle runtime errors in the component. If you do not handle an
error, it is automatically translated into an exception and the component
stops executing.
PowerBuilder client applications that use EAServer components can handle exceptions
thrown by any type of EAServer component.
If a Java EAServer component has
a method on it that is defined to throw an exception and a PowerBuilder
proxy is created to use that component, the method on the PowerBuilder
proxy is also declared to throw a user-defined exception. The definition
of the user-defined exception is created automatically at the time
of the PowerBuilder proxy creation.
For more information about error handling in EAServer clients, see “Handling errors “.
IDL restrictions
Deployment of components to EAServer imposes restrictions
on the way you can use exception handling within PowerBuilder. Only
the public instance variables defined on the exception type are
actually translated to IDL. This is because IDL exceptions cannot
have methods declared on them. Therefore if the exception type has
methods defined on it, those methods can be called within the execution
of the component but cannot be called by client applications that
catch the exception thrown.
You must keep this restriction in mind when designing exception
objects for distributed applications, exposing all exception information
as public instance variables instead of through accessor methods
on an exception object.
Two other interface restrictions also apply to exception types
of a user object that is deployed as an EAServer component.
Instance variables of exceptions on the user object methods cannot
have object datatypes. Null data is supported only for instance
variables with simple datatypes; if instance variables are structures
or arrays, null values for individual elements are not maintained.