SAP ABAP - 异常处理

  • 简述

    exception是程序执行过程中出现的问题。当异常发生时,程序的正常流程被打乱,程序应用程序异常终止,这是不推荐的,因此需要对这些异常进行处理。
    异常提供了一种将控制从程序的一个部分转移到另一个部分的方法。ABAP 异常处理基于三个关键字 - RAISE、TRY、CATCH 和 CLEANUP。假设某个块将引发异常,则方法将使用 TRY 和 CATCH 关键字的组合来捕获异常。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− 程序使用异常处理程序在程序中要处理问题的位置捕获异常。CATCH关键字表示捕获异常。
    CLEANUP− 每当 TRY 块中发生异常且同一 TRY - ENDTRY 构造的处理程序未捕获异常时,就会执行 CLEANUP 块的语句。在CLEANUP子句中,系统可以将对象恢复到一致状态或释放外部资源。即,可以对TRY块的上下文执行清理工作。
  • 引发异常

    可以在方法、功能模块、子例程等中的任何点引发异常。有两种方式可以引发异常 -
    • ABAP 运行时系统引发的异常。
      例如,Y = 1 / 0。这将导致 CX_SY_ZERODIVIDE 类型的运行时错误。
    • 程序员引发的异常。
      同时引发并创建异常对象。使用第一个场景中已存在的异常对象引发异常。语法为:引发异常 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 异常。这里异常类的GET_TEXT()方法用于获取异常的描述。

    异常的属性

    以下是异常的五个属性和方法 -
    序号 属性及描述
    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