13.[SAP ABAP] RAISE 语句详解

13.[SAP ABAP] RAISE 语句详解

文章目录

在ABAP中, RAISE语句用于 触发(抛出)异常 。根据使用的是 经典异常 还是 基于类的异常RAISE的语法和用法有所不同。本章重是基于类的异常中的 RAISE EXCEPTION语句。

一、基于类异常

1. 基本语法

ABAP 复制代码
RAISE EXCEPTION TYPE <异常类名>
      [EXPORTING <参数> = <值> ... ].
  • <异常类名>:必须是继承自 CX_ROOT 的异常类(如 CX_STATIC_CHECKCX_DYNAMIC_CHECK 或自定义异常类)。
  • EXPORTING:用于传递构造异常对象所需的参数(如消息文本、错误码等)。

2. 不同类型异常的抛出

1.抛出类异常(Class-Based Exceptions)
ABAP 复制代码
" 基本用法
RAISE EXCEPTION TYPE cx_sy_zerodivide.

" 带参数
RAISE EXCEPTION TYPE cx_demo_exception
      EXPORTING
         hreadid  = cx_demo_exception => invalid_input
         previous = previous_exception_ref
         value    = '错误值'.
         
" 创建异常对象再抛出
DATA(lx_exception) = NEW cx_sy_arithmetic_error(
        hreadid   =  cx_sy_arithmetic_error => overflow
        previous  = VALUE #()
)
RAISE EXCEPTION lx_exception.
2.抛出非类异常(Legacy Exceptions)
ABAP 复制代码
" 老式异常(不推荐,仅维护旧代码使用)
RAISE division_by_zero.
" 可恢复异常
RAISE resumable_exception 
3.定义自定义异常类
ABAP 复制代码
CLASS zcx_my_exception DEFINITION
  INHERITING FROM cx_static_check
  PUBLIC
  FINAL
  CREATE PUBLIC.
  
  PUBLIC SECTION.
    INTERFACES if_t100_message. " 支持消息文本
    
    CONSTANTS:
       BEGIN OF invalid_input,
          hreadid  TYPE symsgid VALUE 'GOMSG',
          msgid    TYPE symsgid VALUE 'GOMSG',
          attr4 TYPE scx_attrname VALUE '',
       END OF invalid_input. 
       
  DATA:
      value1 TYPE string,
      value2 TYPE string.

  METHODS:
     constructor
        IMPORTING
          textid   LIKE if_t100_message=>t100key OPTIONAL
          previous LIKE previous OPTIONAL
          value1   TYPE string OPTIONAL
          value2   TYPE string OPTIONAL.
ENDCLASS.
4.定义自定义异常类
ABAP 复制代码
" 在方法中声明异常
METHODS validate_input
  IMPORTING
    input_value TYPE string
  RAISING
    zcx_my_exception.  " 声明可能抛出的异常

METHOD validate_input.
  IF input_value IS INITIAL.
    RAISE EXCEPTION TYPE zcx_my_exception
      EXPORTING
        textid = zcx_my_exception=>invalid_input
        value1 = input_value
        value2 = '不能为空'.
  ENDIF.
ENDMETHOD.
5.方法中抛出异常
ABAP 复制代码
METHOD divide_numbers
  IMPORTING
    dividend TYPE i
    divisor  TYPE i
  RETURNING
    VALUE(result) TYPE i
  RAISING
    cx_sy_zerodivide
    cx_sy_arithmetic_overflow.

  IF divisor = 0.
    RAISE EXCEPTION TYPE cx_sy_zerodivide.
  ENDIF.
  
  result = dividend / divisor.
  
  " 检查溢出
  IF result > 1000000.
    RAISE EXCEPTION TYPE cx_sy_arithmetic_overflow
      EXPORTING
        operation = 'DIVISION'
        value     = CONV string( result ).
  ENDIF.
ENDMETHOD.
6.函数模块中抛出异常
ABAP 复制代码
FUNCTION z_function_validate.
*"---------------------------------------------------------
*" 抛出异常
*"---------------------------------------------------------
  IF sy-subrc <> 0.
    RAISE EXCEPTION TYPE cx_bo_error
      EXPORTING
        textid = cx_bo_error=>invalid_parameter.
  ENDIF.
ENDFUNCTION.
7. FORM 中抛出异常
ABAP 复制代码
FORM process_data
  RAISING
    cx_sy_conversion_error.

  DATA: lv_number TYPE i.
  
  TRY.
      lv_number = CONV i( 'ABC' ).
    CATCH cx_sy_conversion_error INTO DATA(lx_error).
      RAISE EXCEPTION lx_error.  " 重新抛出
  ENDTRY.
ENDFORM.
8.FORM 中抛出异常
ABAP 复制代码
FORM process_data
  RAISING
    cx_sy_conversion_error.

  DATA: lv_number TYPE i.
  
  TRY.
      lv_number = CONV i( 'ABC' ).
    CATCH cx_sy_conversion_error INTO DATA(lx_error).
      RAISE EXCEPTION lx_error.  " 重新抛出
  ENDTRY.
ENDFORM.
9.异常链(Exception Chaining)
ABAP 复制代码
METHOD process_data.
  TRY.
      " 第一步处理
      step1( ).
      
    CATCH cx_step1_error INTO DATA(lx_step1).
      " 包装异常
      RAISE EXCEPTION TYPE cx_process_error
        EXPORTING
          textid   = cx_process_error=>processing_failed
          previous = lx_step1
          step     = 'STEP1'.
          
  ENDTRY.
ENDMETHOD.
10.可恢复异常 (Resumable Exceptions)
ABAP 复制代码
" 定义可恢复异常
CLASS cx_resumable_exception DEFINITION
  INHERITING FROM cx_no_check
  RESUMABLE FINAL.  " RESUMABLE 关键字

METHOD process_with_resume.
  TRY.
      RAISE RESUMABLE EXCEPTION TYPE cx_resumable_exception
        EXPORTING
          textid = cx_resumable_exception=>resume_required.
      
    CATCH BEFORE UNWIND cx_resumable_exception INTO DATA(lx_ex).
      " BEFORE UNWIND 在栈展开前执行
      IF can_resume = abap_true.
        RESUME.  " 恢复执行
      ENDIF.
  ENDTRY.
  
  " 如果恢复了,继续执行这里
  WRITE: / 'Execution resumed'.
ENDMETHOD.
10.推荐使用RAISE
ABAP 复制代码
" 1. 使用具体的异常类型
RAISE EXCEPTION TYPE cx_sy_zerodivide.  " 而不是 cx_root

" 2. 提供有意义的错误信息
RAISE EXCEPTION TYPE zcx_validation_error
  EXPORTING
    textid    = zcx_validation_error=>invalid_email
    email     = lv_email
    fieldname = 'EMAIL'.

" 3. 保留原始异常链
CATCH cx_sy_conversion_error INTO DATA(lx_conv).
  RAISE EXCEPTION TYPE zcx_business_error
    EXPORTING
      previous = lx_conv
      textid   = zcx_business_error=>conversion_failed.

" 4. 在方法签名中声明异常
METHODS process
  RAISING
    cx_sy_file_io_error
    zcx_business_error.
11.性能注意事项
  • 异常处理比正常返回开销大
  • 避免在循环中频繁抛出异常
  • 对于可预期的错误,使用返回值检查
  • 异常应用于真正的异常情况

总结:RAISE EXCEPTION是 ABAP 中处理错误情况的标准方式,应该优先于设置 sy-subrc的老式错误处理。

相关推荐
旧巷烟火1 天前
PS成长之路⑩:如何通过WBS进行项目人工成本的精准归集
sap·ps·erp
爱喝水的鱼丶4 天前
SAP-ABAP:全面破解SAP与第三方系统集成超时难题:从应急排查到根治方案
开发语言·sap·abap·接口集成·开发交流
乐乐82344 天前
处理大数据用游标 CURSOR
abap
燚㵘䲜5 天前
CL_GUI_FRONTEND_SERVICES常用method
abap
xlxxy_9 天前
abap 批量创建供应商
运维·开发语言·sap·abap·pp·mm
淋了一场太阳雨10 天前
ABAP 使用函数获取替代(Substitution)值
sap·abap·函数·替代·subsititution
爱喝水的鱼丶11 天前
SAP-ABAP:在SAP世界里与特殊字符“斗智斗勇”:一份来自实战的避坑指南
运维·服务器·数据库·学习·sap·abap·特殊字符
淋了一场太阳雨11 天前
SAP VOFM Material determination
sap·abap
goyeer13 天前
18.[SAP ABAP] 内表(Internal Table)
sap·abap
duangww15 天前
测试SAP的接口账号密码
abap