Ausnahmeklassen sind Unterklassen der globalen Klassen
CX_STATIC_CHECK
CX_DYNAMIC_CHECK
CX_NO_CHECK
Die gemeinsame Oberklasse dieser Klassen ist CX_ROOT. Die Zuordnung zu einer dieser drei Oberklassen bestimmt die Ausnahmekategorie, d.h., ob eine Ausnahme beim
Propagieren aus einer Prozedur explizit in deren Schnittstelle deklariert sein muss und wie die Deklaration überprüft wird:
Wenn Ausnahmen, die über Unterklassen von CX_STATIC_CHECK definiert sind, aus einer Prozedur
propagiert werden, müssen sie explizit in der Schnittstelle der Prozedur deklariert sein. Die
Syntaxprüfung überprüft statisch, ob alle in der Prozedur mit RAISE EXCEPTION oder dem Zusatz THROW in einem
bedingten Ausdruck ausgelösten oder
in den Schnittstellen von aufgerufenen Prozeduren deklarierten Ausnahmen entweder mit CATCH behandelt oder explizit in der Schnittstelle deklariert sind, und gibt andernfalls eine Warnung aus.
Wenn Ausnahmen, die über Unterklassen von CX_DYNAMIC_CHECK definiert sind, aus einer Prozedur
propagiert werden, müssen sie explizit in der Schnittstelle der Prozedur deklariert sein. Dies
wird aber nicht statisch von der Syntaxprüfung, sondern dynamisch in dem Moment überprüft, wenn eine solche Ausnahme aus einer Prozedur propagiert wird.
Ausnahmen, die über Unterklassen von CX_NO_CHECK definiert sind, dürfen nicht explizit
in der Schnittstelle der Prozedur deklariert werden. Die Klasse CX_NO_CHECK und damit ihre Unterklassen sind implizit immer deklariert und werden immer propagiert, wobei eine eventuelle
Wiederaufsetzbarkeit erhalten bleibt.
Wenn eine nicht in der Schnittstelle einer Prozedur deklarierte Ausnahme aus der Prozedur
propagiert wird, verletzt dies die Schnittstelle
und es kommt an der Aufrufstelle der Prozedur zur Ausnahme der vordefinierten Klasse CX_SY_NO_HANDLER, deren Ausnahmeobjekt im Attribut PREVIOUS eine Referenz auf die ursprüngliche Ausnahme enthält.
In der Regel sollten Ausnahmen, die in einer Prozedur auftreten, entweder dort behandelt oder in
der Schnittstelle der Prozedur deklariert werden, um dem Aufrufer mitzuteilen, welche Ausnahmen er zu
erwarten hat. Ausnahmen der Kategorie CX_STATIC_CHECK werden dahingehend syntaktisch überprüft.
Diese Kategorie ist immer dann gerechtfertigt, wenn eine Prozedur gezwungen werden soll, eine Ausnahme
zu behandeln oder zumindest explizit weiter zu leiten. Wenn eine Ausnahme aber durch vorhergehende Prüfungen sicher verhindert werden kann, sind Ausnahmen der Kategorie CX_DYNAMIC_CHECK vorzuziehen.
Wenn die Programmlogik potenzielle Fehlersituationen ausschließen kann, müssen die
zugehörigen Ausnahmen nicht behandelt oder in der Schnittstelle deklariert werden. Dies ist beispielsweise
der Fall, wenn vor einer Division explizit gefordert wird, dass der Nenner ungleich Null ist (precondition).
Für diesen Fall können und sollen Ausnahmen der Kategorie CX_DYNAMIC_CHECK verwendet werden.
Diese Ausnahmen brauchen nur behandelt oder deklariert werden, wenn ihr Auftreten nicht anders ausgeschlossen
werden kann. In gut modellierten Anwendungen werden Ausnahmen in der Regel bereits durch entsprechende
Bedingungen programmatisch verhindert und die Kategorie CX_DYNAMIC_CHECK sollte dann die häufigste Ausnahmekategorie sein.
Für Ausnahmesituationen, die praktisch jederzeit auftreten können und nicht an Ort
und Stelle behandelt werden sollen oder können, ist die Kategorie CX_NO_CHECK vorgesehen. Ansonsten
müssten beispielsweise alle Ausnahmen abgefangen oder deklariert werden, die bei Ressourcenengpässen
auftreten können. Dies würde dazu führen, dass diese Ausnahmen dann in fast jeder
Schnittstelle angegeben werden müssten, was Programme sehr schnell unübersichtlich machen würde.
Die meisten vordefinierten Ausnahmen CX_SY_...
für Fehlersituationen in der Laufzeitumgebung sind Unterklassen von CX_DYNAMIC_CHECK. Dadurch
muss nicht jede potenzielle Ausnahme jeder ABAP-Anweisung behandelt bzw. deklariert werden, sondern nur solche, deren Auftreten nicht ausgeschlossen werden kann.
Der Aufrufer einer Prozedur muss immer damit rechnen, dass die Prozedur neben den explizit deklarierten Ausnahmen auch Ausnahmen der Kategorie CX_NO_CHECK propagiert. Einige der vordefinierten Ausnahmen
CX_SY_... für Fehlersituationen in der Laufzeitumgebung sind Unterklassen von CX_NO_CHECK.
Die Verletzung einer Schnittstelle kommt im Regelfall nur für Ausnahmen der Kategorie CX_DYNAMIC_CHECK
vor, da Ausnahmen der Kategorie CX_STATIC_CHECK schon von der Syntaxprüfung überprüft werden und Ausnahmen der Kategorie CX_NO_CHECK jede Schnittstelle passieren können.
Ob eine Ausnahme wiederaufsetzbar
ist oder nicht, ist keine Eigenschaft der Ausnahmeklasse sondern wird beim Auslösen der Ausnahme
mit dem Zusatz RESUMABLE der Anweisung RAISE EXCEPTION oder bei dem Zusatz THROW in einem
bedingten Ausdruck festgelegt. Diese Eigenschaft
kann für Ausnahmen der Arten CX_STATIC_CHECK und CX_DYNAMIC_CHECK beim Propagieren durch Parameterschnittstellen
von Prozeduren verloren gehen, wenn sie dort nicht ebenfalls mit RESUMABLE deklariert sind.