13.[SAP ABAP] RAISE 语句详解
文章目录
- [13.[SAP ABAP] RAISE 语句详解](#13.[SAP ABAP] RAISE 语句详解)
-
- 一、基于类异常
-
- [1. 基本语法](#1. 基本语法)
- [2. 不同类型异常的抛出](#2. 不同类型异常的抛出)
-
- [1.抛出类异常(Class-Based Exceptions)](#1.抛出类异常(Class-Based Exceptions))
- [2.抛出非类异常(Legacy Exceptions)](#2.抛出非类异常(Legacy Exceptions))
- 3.定义自定义异常类
- 4.定义自定义异常类
- 5.方法中抛出异常
- 6.函数模块中抛出异常
- [7. FORM 中抛出异常](#7. FORM 中抛出异常)
- [8.FORM 中抛出异常](#8.FORM 中抛出异常)
- [9.异常链(Exception Chaining)](#9.异常链(Exception Chaining))
- 10.可恢复异常 (Resumable Exceptions)
- 10.推荐使用RAISE
- 11.性能注意事项
在ABAP中, RAISE语句用于 触发(抛出)异常 。根据使用的是 经典异常 还是 基于类的异常 。 RAISE的语法和用法有所不同。本章重是基于类的异常中的 RAISE EXCEPTION语句。
一、基于类异常
1. 基本语法
ABAP
RAISE EXCEPTION TYPE <异常类名>
[EXPORTING <参数> = <值> ... ].
<异常类名>:必须是继承自CX_ROOT的异常类(如CX_STATIC_CHECK、CX_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的老式错误处理。