SAP ABAP 异常处理
异常 是程序执行过程中出现的问题。当发生异常时,程序的正常流程会中断,程序应用程序会异常终止,因此应处理这些异常。
ABAP 针对异常提供了一种将控制权从程序的一部分转移到另一部分的方法。
ABAP 异常处理基于这几个关键字: RAISE
, TRY
, CATCH
和 CLEANUP
。
假设一个代码块将引发异常,那么一个方法将使用 TRY
和 CATCH
关键字的组合来捕获异常。
下面是 TRY – CATCH
的语法:
TRY.
Try Block <Code that raises an exception>
CATCH
Catch Block <exception handler M>
. . .
. . .
. . .
CATCH
Catch Block <exception handler R>
CLEANUP.
Cleanup block <to restore consistent state>
ENDTRY.
RAISE
- 异常发生,通常,异常处理程序会尝试修复错误或找到替代解决方案。TRY
- TRY 代码块包含要处理其异常的应用程序编码。此语句块按顺序处理。它可以包含进一步的控制结构和过程调用或其他 ABAP 程序。它后面跟着一个或多个代码块。CATCH
- 程序在程序中要处理问题的位置使用异常处理程序捕获异常。CATCH 关键字表示捕获异常。CLEANUP
- 每当 TRY 代码块中发生异常,而该异常未被同一TRY-ENDTRY
构造的处理程序捕获时,就会执行 CLEANUP 代码块的语句。在 CLEANUP 子句中,系统可以将对象恢复到一致状态或释放外部资源。也就是说,可以对 TRY 代码块的上下文执行清理工作。
发生异常
异常可以在方法、函数模块、子例程等中的任意位置发生。
有两种方法可以引发异常:
- ABAP运行时系统引发的异常。例如,Y = 1 / 0。这将导致
CX_SY_ZERODIVIDE
类型的运行时错误。 - 程序员引发的异常。同时引发和创建异常对象。使用第一个方案中已存在的异常对象引发异常。语法为:
RAISE EXCEPTION exep
。
捕获异常
处理程序用于捕获异常。
让我们看一段代码片段:
DATA: result TYPE P LENGTH 8 DECIMALS 2,
exref TYPE REF TO CX_ROOT,
msgtxt TYPE STRING.
PARAMETERS: Num1 TYPE I, Num2 TYPE I.
TRY.
result = Num1 / Num2.
CATCH CX_SY_ZERODIVIDE INTO exref.
msgtxt = exref→GET_TEXT( ).
CATCH CX_SY_CONVERSION_NO_NUMBER INTO exref.
msgtxt = exref→GET_TEXT( ).
在上面的代码段中,我们尝试将 Num1
除以 Num2
,以得到浮点型变量中的结果。
可以生成两种类型的异常:
- 数字转换错误。
- 除零异常。处理程序捕获
CX_SY_CONVERSION_NO_NUMBER
异常以及CX_SY_ZERODIVIDE
异常。这里使用 exception 类的GET_TEXT()
方法来获取异常的描述。
异常属性
以下是异常的 5 个属性和方法:
编号 | 属性 & 描述 |
---|---|
1 | Textid 用于为异常定义不同的文本,还影响方法 get_text 的结果。 |
2 | Previous 此属性可以存储可以让您构建异常链的原始异常。 |
3 | get_text 这将根据异常的系统语言以字符串形式返回文本表示形式。 |
4 | get_longtext 这将异常的文本表示形式的长变量作为字符串返回。 |
5 | get_source_position 给出引发异常的程序名和到达的行号。 |
实例
REPORT ZExceptionsDemo.
PARAMETERS Num_1 TYPE I.
DATA res_1 TYPE P DECIMALS 2.
DATA orf_1 TYPE REF TO CX_ROOT.
DATA txt_1 TYPE STRING.
start-of-selection.
Write: / 'Square Root and Division with:', Num_1.
write: /.
TRY.
IF ABS( Num_1 ) > 150.
RAISE EXCEPTION TYPE CX_DEMO_ABS_TOO_LARGE.
ENDIF.
TRY.
res_1 = SQRT( Num_1 ).
Write: / 'Result of square root:', res_1.
res_1 = 1 / Num_1.
Write: / 'Result of division:', res_1.
CATCH CX_SY_ZERODIVIDE INTO orf_1.
txt_1 = orf_1→GET_TEXT( ).
CLEANUP.
CLEAR res_1.
ENDTRY.
CATCH CX_SY_ARITHMETIC_ERROR INTO orf_1.
txt_1 = orf_1→GET_TEXT( ).
CATCH CX_ROOT INTO orf_1.
txt_1 = orf_1→GET_TEXT( ).
ENDTRY.
IF NOT txt_1 IS INITIAL.
Write / txt_1.
ENDIF.
Write: / 'Final Result is:', res_1.
在此实例中,如果数字大于 150,则会引发异常 CX_DEMO_ABS_TOO_LARGE
。
上述代码为数字 160 生成以下输出的结果:
Square Root and Division with: 160
The absolute value of number is too high
Final Result is: 0.00