Exceptions

Each exception text must have an explanatory text assigned to it that describes the exception in more detail. The emphasis is on displaying a meaningful error message if an exception cannot be caught, rather than on the interaction between the program and the user.

To ensure that message texts describe the error situation as well as possible, you can set parameters for exception texts using the textual attributes of the exception object. Textual in this context means that the attribute must have a scalar type - for example, a C field, a string, or an integer. You cannot use an internal table, object reference, or structure.

You can include attributes in the text by enclosing their name in ampersands (&). If you want to use the ampersand character itself, you must enter it twice.

Example

The text
    Kanzlei &ANWALT&&&&PARTNER&
together with the following attributes:
   ANWALT  = 'Müller'
   PARTNER = 'Meier'

would cause the following text to be displayed:
   Kanzlei Müller&Meier


Replacing parameters in exception texts must not cause any errors. For this reason, the following rules apply:

Example

The text
    Error number &ERRID& in the file '&FILE&'
together with an exception object that contains only the FILE attribute, with the following value:
   FILE = '/home/sap/data/output/dir1/some_subdir_with_a_very_long_name/outfile'
would cause the following text to be displayed:
   Error number &ERRID& in the file '/home/sap/data/output/dir1/some_sub...'

Exception texts are language-specific and have to be translated. The texts are managed in the ONLINE TEXT REPOSITORY (OTR). The dedicated text is assigned to the exception object using the TEXTID attribute, as defined in CX_ROOT. At runtime, the attribute contains the unique global identity of the OTR text object, which provides the text when the GET_TEXT method is called, and the parameters are substituted. The substituted text is then returned in the form of a string.

The texts are assigned declaratively - the Exception Builder offers the support you need. It stores the texts in the OTR and generates the associated class constants, whose value corresponds to the OTR key of the text object. Programmers can then use the abstract name of the class constant - they do not need to know the OTR keys. Generating the class constructor appropriately ensures that an exception class is always assigned to a text: if there is no text defined for a class, the text of the next class up is used.

It often makes sense to assign an exception class to several texts - for example, if there are several specific situations where an exception could occur. By doing so, you get round the need to create a separate exception class for each special situation. You can differentiate between the different situations using the TEXTID. However, you should only use this mechanism if all these situations use the same attributes and if the handlers are only interested in this extra level of detail in rare cases. Even if you assign several texts to an exception class, you should always designate one of them as the default. The Exception Builder uses the convention that the ID of the default text matches the name of the exception class itself. You can define other texts using any ID you want. However, you must bear in mind that the Exception Builder creates corresponding class constants, so the names must not conflict with existing attribute names in the inheritance tree.

Example

As an example, consider the class CX_SY_CREATE_OBJECT_ERROR. An exception of this type is raised if an error occurred when an object was generated. For most handlers, the reasons for the error are immaterial. However, there are several possible causes - for example, the class may not exist, or the constructor may be private (or protected). All these reasons make reference to a single attribute, the name of the class. Consequently, no sub-classes are created for these special situations. Instead, they are represented by different texts. The texts are addressed using several different class constants, namely UNKNOWN_CLASS, PRIVATE_CONSTRUCTOR, PROTECTED_CONSTRUCTOR etc. This allows the handler to differentiate between the different cases as follows:

DATA: ex TYPE REF TO CX_SY_CREATE_OBJECT_ERROR.
TRY.
  ... " Protected area with object generation.
CATCH CX_SY_CREATE_OBJECT_ERROR INTO ex.
  CASE ex->textid.
    WHEN CX_SY_CREATE_OBJECT_ERROR=>CX_SY_CREATE_OBJECT_ERROR.
      ...
    WHEN CX_SY_CREATE_OBJECT_ERROR=>UNKNOWN_CLASS.
      ...
    WHEN CX_SY_CREATE_OBJECT_ERROR=>PRIVATE_CONSTRUCTOR OR
         CX_SY_CREATE_OBJECT_ERROR=>PROTECTED_CONSTRUCTOR.
      ...
  ENDCASE.
ENDTRY.

Thus, when an exception is raised, the system triggers a specific case by explicitly setting the TEXTID attribute. For example, the following statement raises an exception of the CX_SY_CREATE_OBJECT_ERROR type with a default text.

RAISE EXCEPTION TYPE CX_SY_CREATE_OBJECT_ERROR
    EXPORTING classname = 'SOME_CLASS'.

Conversely, the following statement raises an exception of the CX_SY_CREATE_OBJECT_ERROR type for an unavailable class.

RAISE EXCEPTION TYPE CX_SY_CREATE_OBJECT_ERROR
    EXPORTING classname = 'SOME_CLASS'
              textid    = CX_SY_CREATE_OBJECT_ERROR=>UNKNOWN_CLASS.

Additional help

Class-Based Exceptions