This chapter provides an overview of Exception class and discusses the following topics:
How exceptions are thrown.
When to use exceptions.
Try-Catch sections.
Data Type for Exception class objects.
Scope of Exception class objects.
Exception class built-in function and language constructs.
Exception class methods.
Exception class properties.
An exception can be defined as any unusual event that requires special handling in your PeopleCode program. This could include some kind of hardware failure, such as trying to write to a printer that's been turned off, or a software failure, such as trying to divide by zero. You can also detect your own errors, and use the Throw statement to construct an exception.
Exception handling is the processing you initiate when an exception occurs. You can handle errors in PeopleCode using the Catch statement. The places in your code where you want exceptions handled must be enclosed by the Try and End-Try statements.
The Exception class encapsulates exceptional runtime conditions. It can be used with most PeopleCode programs.
Note. The Exception class does not work with any of the PeopleSoft APIs, that is, the classes whose objects are declared as type ApiObject. This includes the Tree classes, the Query classes, Search classes, and so on.
The process of error handling can be broken down as follows:
An error occurs (either a hardware or software error).
The error is detected and an exception is thrown (either by the system or by your program).
Your exception handler provides the response.
Exceptions get thrown either by the runtime system or by your program.
In general, the kinds of errors that cause the runtime system to throw an exception are errors that terminate your PeopleCode program. For example, dividing by zero, referencing a method or property that doesn't exist, or trying to use a method or property on a null object.
To throw your own exceptions, you can use the Throw statement.
If the error is something that you can easily check, you shouldn't use exceptions. For example, suppose your page had begin and end date fields. In your SavePreChange PeopleCode program, you would want to check to verify that the end date was after the begin date. This kind of error produces incorrect data. It doesn't terminate your PeopleCode program. This is a simple check, one that you don't need to throw an exception for.
Errors that you might want to use exceptions for are the kinds that you are going to check for often. It might make more sense to have a single exception class for that kind of error, so you'd only have to write your error handling code once.
For example, suppose that a function you called was supposed to return an array object that you'd then manipulate using the array class methods and properties. When the function fails and doesn't return an array object, you can either check for Null, or check for an exception (as this kind of error terminates your PeopleCode program.) If you must often check for Nulls, perhaps instead of constantly checking, you could rely on the runtime system throwing exceptions for you.
Pseudo code example:
Import ExceptionPackage:*; /* this package contains all the exception classes for your app */ try &MyArray = GetArrayData(&Param1, &Param2, &Param3); /* Code to manipulate &MyArray here */ catch ExceptionNull &Ex1 if &Ex1.MessageSetNumber = 2 and &Ex1.MessageNumber = 236 Then /* this is the message set and message number for &MyArray being Null */ /* do data error handling */ end-if; end-try;
Considerations Using Exceptions and Transfer Functions
Using functions that transfer the end user to a new component, such as the DoModal, DoModalComponent, or Transfer functions (in some cases) inside a try block do not catch PeopleCode exceptions thrown in the new component. Starting a new component starts a brand new PeopleCode evaluation context. Catches are only caught for exceptions thrown within the current component.
In the following code example, the catch statement only catches exceptions thrown in the code prior to using the DoModal function, but not any exceptions that are thrown within the new component.
/* Set up transaction */ If %CompIntfcName = "" Then try &oTrans = &g_ERMS_TransactionCollection.GetTransactionByName(RB_EM_WRK.DESCR); &sSearchPage = &oTrans.SearchPage; &sSearchRecord = &oTrans.SearchRecord; &sSearchTitle = &oTrans.GetSearchPageTitle(); If Not All(&sSearchPage, &sSearchRecord, &sSearchTitle) Then Error (MsgGetText(17834, 8081, "Message Not Found")); End-If; &c_ERMS_SearchTransaction = &oTrans; /* Attempt to transfer to hidden search page with configurable filter */ &nModalReturn = DoModal(@("Page." | &sSearchPage), &sSearchTitle, - 1, - 1); catch Exception &e Error (MsgGetText(17834, 8082, "Message Not Found")); end-try;
The statements that immediately follow the Try statement are called the protected statements. These are the only statements that are 'protected' by the catch clauses in the Try-Catch statements. The catch clauses in a Try-Catch statement can be executed only if an exception is thrown by the protected statements. In addition, a catch clause is executed only when handling an exception that matches the type given on the catch. Any exceptions thrown by the catch clauses are not caught by their own Try-Catch statement.
The execution of the Try-Catch statement starts by executing the protected statements. If none of these statements, as well as none of the statements called by them, causes an exception to be thrown, the try-catch is done. The statements in the catch clauses are not executed.
Each catch clause in the Try-Catch section declares a local variable of class Exception or a subclass of Exception. A catch clause local variable has the same scope and lifetime as a local variable declared at the start of the catch clause.
The following is the general order of exception execution and handling in the Try-Catch statements.
The exception is thrown.
The exception is considered by the first enclosing Try-Catch statement.
Try-catch statements can be nested.
This is a dynamic enclosure, that is, tracking back through method and function callers. Any intervening non-Try-Catch statements are skipped.
Within this Try-Catch statement, the catch clauses are considered in program text order, that is, first the first catch clause is considered, then the next, and so on to the last. At each consideration, the type (class) of the exception being thrown is compared to the type of the local variable declared by the Catch clause. If the exception being thrown is the same as the Catch type, or is a subtype of it (so the exception could be assigned to the Catch's local variable) the Catch clause matches the exception being thrown.
If a matching catch clause is found, that catch clause handles the exception. The exception is considered 'caught', which means that it does not propagate further. Execution proceeds by assigning the thrown object to the catch clause’s local variable and executing the statements in the catch clause. When one of the catch clauses handles the exception, (and the statements in the catch clause don’t throw any further exceptions), execution continues normally after the Try-Catch statement.
If a statement in the catch clause throws another exception, that exception begins to propagate from the point of the throw.
If a matching catch clause is not found, that is, if no catch clauses can accept the thrown object, then the thrown object is still uncaught. The thrown object is considered by the next dynamically enclosing Try-Catch statement (return to step 3).
If a thrown object is not caught by any catch clause in any dynamically enclosing Try-Catch statements, a fatal PeopleCode evaluation error is produced.
Exception Class objects are declared as type Exception. For example:
Local Exception &Ex1;
Exception objects can be instantiated only from PeopleCode. This object can be used anywhere you have PeopleCode, that is, in message subscription PeopleCode, Component Interface PeopleCode, record field PeopleCode, and so on.
In this section, we discuss the Exception class methods, in alphabetical order.
Syntax
GetSubstitution(Index)
Description
When you create a message in the message catalog, you can specify values in the message text, such as %1, %2, and so on, that are replaced with values by the system at runtime. The value that gets put into the message text value is called the substitution string. The GetSubstitution method returns the substitution string in the error message specified by Index, with 1 being the first substitution string, 2 being the second, and so on.
Parameters
Index |
Specify the substitution string number that you'd like to return. The first one is 1, the second is 2, and so on. You must specify a valid substitution string number, that is, you can't specify a 4 if there are only three substitution strings. |
Returns
The substitution text as a string.
Example
If &Ex1.MessageSetNumber = 2 and &Ex1.MessageNumber = 170 Then /* Get Sendmail error */ &String = &Ex1.GetSubstitution(1); /* do processing according to type of Sendmail error */ . . . . End-if;
See Also
Exception class: SetSubstitution method.
Syntax
Output()
Description
Use the Output method if you want to display the message associated with the exception to the user (in an online context), or have it logged (if offline). This is analogous to using the MessageBox function to log a message.
Parameters
None.
Returns
If called in an online context, display the message associated with the exception to the user. If called offline, record the exception for later display or analysis.
Example
catch Except2 &Ex2 &Ex2.Output(); /* tell about it */
See Also
Syntax
SetSubstitution(Index, String)
Description
When you create a message in the message catalog, you can specify values in the message text, such as %1, %2, and so on, that are replaced with values by the system at runtime. The value that gets put into the message text value is called the substitution string. The SetSubstitution method sets the substitution string in the error message specified by Index, with 1 being the first substitution string, 2 being the second, and so on.
Parameters
Index |
Specify the substitution string number that you'd like to replace. The first one is 1, the second is 2, and so on. You must specify a valid substitution string number, that is, you can't specify a 4 if there are only three substitution strings. |
String |
Specify the text of the substitution string. |
Returns
None.
See Also
Exception class: GetSubstitution method.
Syntax
ToString([AddContext])
Description
The ToString method returns the expanded message text associated with the exception in the current user's current language. The string returned is the message text (in the current user's language) with the substitution string replacing the substitution markers (%1 and so on) in the text. It always returns the context information about where the error occurred at the end of the message. To suppress this, specify AddContext as false.
Parameters
AddContext |
Specify whether to have the context information about where the error occurred added at the end of the message. This parameter takes a Boolean value. The default is true, that is, to add the context information. |
Returns
A string.
See Also
Exception class: Output method.
In this section, we discuss the Exception class properties, in alphabetical order.
Description
This property returns a string description of the location of the condition in PeopleCode or other processing. This might contain a stack backtrace at the point of the exceptional condition.
This property is read-only.
Example
This is the “At” part of the error message display. For example, for an exception thrown in Record.Field Event QE_31DIGREC1.QE_31DIGFLD5 FieldChange function EachComp at PeopleCode program counter 671, statement 11 of the source program, the Context would be:
At QE_31DIGREC1.QE_31DIGFLD5.FieldChange EachComp PCPC:671 Statement:11
Description
This property sets a string to use as the basic message text for the exception when the message can't be found in the message catalog.
This property is read-write.
Description
This property is the message number for a message describing the exceptional condition.
This property is read-only.
Description
This property is the message set number for a message describing the exceptional condition.
This property is read-only.
Description
This property is the message severity as a string for a message describing the exceptional condition. The message severity is set for the message when it's created in the message catalog. The values are:
Numeric Value |
Constant Value |
Description |
C |
%MsgSeverity_Cancel |
Message severity is Cancel. |
E |
%MsgSeverity_Error |
Message severity is Error. |
M |
%MsgSeverity_Message |
Message severity is Message. |
W |
%MsgSeverity_Warning |
Message severity is Warning. |
This property is read-only.
Description
This property returns a string with the complete stack trace. This includes the whole context, (that is, current location + called from X + called from. . . )
You can process the returned string by breaking it into pieces using the Split function, and using "Called from" as the value to use for separating the string. For example,
Local Array of String &Pieces; /* get exception */ &Pieces = Split(&E.StackTrace, "Called from:");
This property is read-only.
Example
The following is an example of a trace stack.
In C (0,0) AEMINITEST.MAIN.GBL.default.1900-01-01.Step02.OnExecute Name:C PCPC :136 Statement:2 Called from:AEMINITEST.MAIN.GBL.default.1900-01-01.Step02.OnExecute Name:B Sta tement:6 Called from:AEMINITEST.MAIN.GBL.default.1900-01-01.Step02.OnExecute Name:A Sta tement:13 Called from:AEMINITEST.MAIN.GBL.default.1900-01-01.Step02.OnExecute Statement:1 8
Description
This property returns the number of substitution strings in the message text as a number.
The number of substitutions comes from the subslist of the CreateException function.
This property is read-only.
See Also