Within C and Fortran, condition codes are returned from function to function. Within C++, error objects are thrown from function to function.
C & FORTRAN C++
error detected error detected
These are detected within application code in a variety of ways. They may be status returned by hardware, something not completing, etc.
If an error is detected within a RTL function and the fact that there was an error can be returned by the function, it does so and the external symbol errno is set to a value which indicates why the error occurred. See the DECC runtime library manual.
If an error indication cannot be returned from the function, a VMS exception is generated as might occur in application code. These can be detected by the use of the VMS exception handling functions. See the VMS condition handling sections in this document.
When an error occurs within a STL function an exception object is thrown. It can be caught by a catch(exception&); statement in a C++ routine. See the VMS condition handling sections in this manual and the DEC help files on the exception class.
These can be detected by the use of the VMS exception handling functions. See the VMS condition handling sections in this document.
When an application function detects an error it must pass the fact of the error to the function which called it.
These functions should return a VMS condition code as the function return.
These functions should instantiate an ErrCondition_C object or an object of a class derived from ErrCondition_C and then throw the pointer to the object. Such as:
Err_C* err_po = new ErrCondition(FACILITY_ERROR);
If additional information is available it be included in the error incident by also instantiating an ErrContext_C object. Such as:
new ErrContext(While doing something.);
These functions should pass on to their caller the condition code returned to them by called functions. See REF_DSPSHR:Demo_Cfunc.c.
These functions should catch an Err_C*, extract the condition code from it, and return the condition code as their function return. See REF_DSPSHR:Demo_CppFunc_cfn.cxx.
These are the objects which can be thrown and caught by C++ routines for the purpose of passing an error condition and its context upward through layers of applications. The formats shown here only indicate the types of arguments that can be used. The exact formats are in the class definition (header/.hxx) file for each class.
This class provides for the instantiation of an object which contains a condition code, optional data, and an optional output destination. Also see: ErrCondition_C.hxx and REF_DSPSHR:Demo_C.cxx
ErrIss_C is a typedef for ErrCondition_C and can be used in its place if desired.
This class provides for the instantiation of an object which provides contextual information for an error incident, and an optional output destination for the information. Also see: ErrContext_C.hxx and REF_DSPSHR:Demo_CppFunc.cxx.
This class provides for the instantiation of an object which provides an additional output destination for an error incident. The total set of output destinations for an incident is the set of all destinations of all objects included in the incident. Also see ErrDestination_C.hxx and the Destinations section of this document.
This class provides for the instantiation of an object which provides an overriding severity for an error incident.
If there is more than one of these in an incident, then the last one entered for the incident will be the one used.
Also see: Err_C.hxx.
Severity refers to the severity of a condition code. It is one of the following: SUCCESS, INFORMATIONAL, WARNING, ERROR, or SEVERE.
This class provides for the instantiation of an object which results in output which is the same as the legacy ERR_SEND() function used in Fortran and C functions. It has been implemented to provide compatibility with the old style. Within C++ one should, instead, instantiate an ErrConditon_C object, providing a UtlArgs_C object as the data.
This class provides for the instantiation of an object which results in output which is the same as the legacy ERR_TEXT() function used in Fortran and C functions. It has been implemented to provide compatibility with the old style. Within C++ one should, instead, instantiate an ErrConditon_C object, providing a UtlString_C object as the data.
This class provides for the instantiation of an object which delimits error instances. It is to be used in AST routines as more than one instance may occur before the queue is processed. It should be instantiated after all other error instantiations in an AST routine prior to the AST function return.
These are the classes which can be used as the data of ErrCondition_C, ErrSend_C, and ErrText_C objects.
This class provides string data. It is instanciated by supplying a null terminated string. In the future you will also be able to include a font and a color.
This class provides time. It has member functions to retrieve the time in rtl type, system type, or as a null terminated text string.
This class provides data associated with a Standard Template Library class. It is instanciated by providing a reference to an exception class object which then becomes the object's data.
This class provides data associated with a VMS exception. It is instanciated by providing a pointer to a VMS signal structure. The data contained in the object is the condition code obtained from the signal structure.
This class provides data which is associated with the arguments of the VMS error message facility. It is instanciated by providing from zero to ten pointers each of which points to a four byte argument. The data contained in the object is the set of the four byte contents of the argument pointers.
This class provides data which is the identification of a SLC database secondary. It contains the primary,micro,unit,secondary, and channel.
This class provides data which is the identification of an Epics database value. It contains up to 4 record subnames and the field name. VAL is used as the field name if none is supplied.
This class provides data which is the identification of parameters used in the DCXP, SIP, and HSTB facilities. It contains either a SLC database primary, micro, unit. secondary, channel identification or a special device, area, unit, parameter identification which is used only within these facilities. A special dcxp parameter name can be used in place of the secondary name for SLC database items. See DCXP, SIP, or HSTB manuals.
This class provides data which is the specification of a help file entry from which text is obtained for output. You provide a set of semicolon separated keys as a null terminated string such as: DISPHELP;MODULE;KEY1;KEY2;...
These are the destinations to which error information can be sent. Also see: Err_C.hxx.
The current SCP error handler will output all information to all destinations contained in the incident.
This is a special destination which is specified by Err_C::DEFAULT_DEST. For this destination the output is generated by the class default output routine. See the class header files.
This destination is the popup operator notification window. It is specified by Err_C::NOTIFICATION_WINDOW_DEST. When output is sent to the window it pops up over the touchpanel in front of the operator. It is dismissed by the operator clicking its cancel button.
This destination is the status bar on the knobs panel. It is specified by Err_C::STATUS_BAR_DEST. When output is done to this destination only the data from the first instantiated object of the incident is displayed in the bar. However, when an operator clicks on the status bar a status window pops up with all output which has been sent to the status bar destination.
For now, the output also goes to the local message window of the SCP.
This destination is a user specified file. The error facility opens and writes to a file named: USER_ERROR_FILE. If you wish, you can define this as a logical to be whatever file you want it to be.
This destination is the errorlog file.
This destination is the operator local message window.
Broadcast to all processes receiving messages. For the SCP these go to the global message window.
These functions can be called from C functions to instantiate a objects to be included in an error instance. There names are not mangled. See err_faciilty.h.
This function creates an instance of an ErrCondition_C object. A vmsstat_t condition code and a null terminated string are the only argument types available.
This function creates an instance of an ErrContext_C object. A null terminated string is the only argument type available.
This function creates an instance of an ErrSend_C object. A variable length argument list of pointers to 4 byte data items is used.
Tis function creates an instance of an ErrText_C object. A null terminated string or a string descriptor can be supplied as the argument.
This function creates an instance of an ErrContext_C object specifying the status bar as the destination. A null terminated string is the only argument type available.
This function creates an instance of an ErrDestination_C object. It adds the specified destination to the set of destinations for the output of an error incident.
This function creates an instance of an ErrSeverity_C object. The specified severity overrides the severities of any entries made for an error incident. If more than one ErrSeverity_C object is included in an error incident, the last one entered is the one used.
This function creates an instance of an ErrContext_C object, supplying it with a UtlHelp_C object as data. The UtlHelp_C object is created using the string passed to this function by descriptor.
The error handling system can be used from within an ast routine. To do so you:
The process executive will call the current handler for the queue that you have created.
All error classes which are available for public usage are in a class hierarchy derived from the Err_C class. All utility data classes are in a separate class hierarchy derived from Utl_C. Each hierarchy provides a complete set of class typing functions. See Err_C.hxx and Utl_C.hxx.
ErrFacility_C* err_facility_po = ErrFacility_C::ErrFacility();
Note that a try-catch-process situation can be inserted anywhere in the process execution where error output is to be done.
Call ErrQueue_C::Handler(user_handler_function(), &user_data); to specify a handler to be used for any current incident. Note that it must be re-specified each time the executive calls an application facility. However, it does not need to be called prior to any items being instanciated for an incident, only prior to control being returned to the executive.
When an error is detected during the execution of the error handling facility code, a fatal VMS condition is signalled and the process will abort.
This user manual: DOC$USER:ERROR_HANDLING_MANUAL.PS.
There is also the design document (not quite up-to-date): DOC$DESIGN:ERROR_HANDLING.PS.
There is a Demo facility within the scp that utilizes the facility.
By selecting the DEMO panel from the user dev panel you can press buttons which create various errors which generate output to various destinations.
The Demo... code in dspshr can be used for reference or as template code. See REF_DSPSHR:Demo*.*.
The following routines contain the various functions which can be used: Demo_AllCalls.cxx, Demo_AllDestinations.cxx, Demo_QueAllCalls.cxx, Demo_AllOperators.cxx, and Demo_ForC.cxx.
The code and classes of the error facility contain most of the C++ issues that one migh t normally encounter when developing any C++ facility.
All information contained in this section reflects my current understanding of how things work. It is subject to change.
Note: Currently there is a VMS problem using cxxl
When a VMS error condition is raised within application code a VMS exception is generated. It is processed by the first VMS exception handler encountered moving down the stack.
If the VMS signal is rethrown (throw;), the next catch(struct chf$signal_array* ps) or VMS condition handler lower on the stack will be called.
If the VMS exception does not have an equivalent Unix signal, the VMS exception can be caught by catch(struct chf$signal_array* ps). If it does have an equivalent, it will not be caught.
However, if cxxl$set_condition(cxx_exception) is in effect when a try block is entered (has been called prior to the try block) then a VMS exception which has an equivalent Unix signal can be caught by a catch(struct chf$signal_array* ps) after the try block.
When an error is detected within application code and a throw is done a VMS exception is generated which is caught by a VMS exception handler established by a catch statement.
When an error occurs within a RTL function.
If it is an error which can be returned from the function, the fact that there was an error is returned and errno is set to indicate why the error occurred. errno is actually a macro which generates a function call.
If an error indication cannot be returned, a VMS exception is generated.
When an error occurs within a STL function an exception object is thrown. It can be caught by catch(exception&) in a C++ routine. Note that this is an exception object not a VMS exception.
All information contained in this section reflects my current understanding of how things work. It is subject to change.
In C++ routines if cxxl$set_condition(cxx_exception) has been called, then a VMS signal can be caught by catch(struct chf$signal_array* ps). If a rethrow is done the VMS signal will continue to be processed.
If cxxl$set_condition(cxx_exception) is in effect, an a RTL signal handler is called and will not return.
If a VMS signal reaches the call frame of the routine which calls LIB$ESTABLISH, then the exception handler specified in the call will be called.
If the exception handler return is a resignal, the VMS signal will continue to propagate down the stack.
If the handler return is a convert to status, the stack will be unwound thru the routine which called LIB$ESTABLISH and the condition code contained in the VMS signal will be returned as the function return.
Note: At this time in the SCP and in our standalones these RTL functions cannot be used as they conflict with our use of VMS exception handlers.
The sig... RTL functions can be used to control what action to take or what handler to call when a unix signal (or any of a set of unix signals) is processed. For this to happen a VMS exception must reach a RTL VMS signal handler where the VMS exception can be processed.
If VAXC$CRTL_INIT is explicitly called, it establishes the RTL handler at the bottom of the stack regardless of wen, or how many times, it is called. If it is not called and the main process routine is not a C or C++ routine, no RTL handler will be established.
If a LIB$ESTABLISH VMS exception handler has been established the RTL handler will only be called unless the exception handler resignals the exception. It does not matter in what order the VAXC$CTRL_INIT and LIB$ESTABLISH calls are done.
If cxxl$set_condition(cxx_exception) has not been called, and a handler established by signal(signal_code, handler) is called and does a return;, execution will continue after the signal() call.
If cxxl$set_condition(cxx_exception) has been called, the "last chance" handler is called when the signal handler returns.
If you wish to have error incident output metered, you can instantiate a destination object with an attached meter object. If any output is suppressed, a counter for the output is incremented and when the output is finaly done, the count is appended to the output.
For now only the meter object most recently entered into the error instance will be used and the metering will be applied to all incident output.
If needed, the facility can be enhanced such that output to specific destinations can be metered separately.
To have metering applied to the incident:
Two types of metering are provided for. The type is determined by which ErrMeter_C constructor is used.
Only one output is allowed during any interval of time.
If the burst count is exceeded within the burst interval then metering will begin and continue until there have been no more incidents the same incidents within the reset interval.