04-10-2008 8:30 PM
Hello all
I'm trying to learn how to use SE24 and I'm a bit stumped on handling exception.
Here's a trivial example showing what I'd like to do.
Can anyone tell me what's wrong. Or point me to a reference.
*& N1 TYPE INT1 Byte Value
*& N2 TYPE INT1 Byte Value
*& OUT TYPE INT1 Byte Value
*& CX_SY_ARITHMETIC_ERROR System Exception for Arithmetic Errors
METHOD mult2.
data: exc type REF TO cx_sy_arithmetic_error .
out = n1 * n2 .
IF out > 9.
RAISE EXCEPTION type exc
ENDIF.
ENDMETHOD.
04-10-2008 8:52 PM
Hello Ed
Using exception classes the rule is the same as in Java:
Either THROW or CATCH the exception.
To catch means to surround the problematic piece of coding using a TRY-CATCH-ENDTRY block.
To throw means to define the exception class as part of the method signature.
The sample report ZUS_SDN_EXCEPTION_IN_LOCCLASS demonstrates how to throw and catch the exception.
*&---------------------------------------------------------------------*
*& Report ZUS_SDN_EXCEPTION_IN_LOCCLASS
*&
*&---------------------------------------------------------------------*
*& Thread: Using exceptions in SE24 global class Builder
*& <a class="jive_macro jive_macro_thread" href="" __jive_macro_name="thread" modifiedtitle="true" __default_attr="817903"></a>
*&---------------------------------------------------------------------*
REPORT zus_sdn_exception_in_locclass.
*----------------------------------------------------------------------*
* CLASS lcl_myclass DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
divide
IMPORTING
id_enumerator TYPE i
id_denominator TYPE i
RETURNING
value(rd_result) TYPE i
RAISING
cx_sy_zerodivide.
ENDCLASS. "lcl_myclass DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_myclass IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass IMPLEMENTATION.
METHOD divide.
" raises division by zero error if id_denominator = 0
rd_result = id_enumerator / id_denominator.
" NOTE: since the exception class is defined within the
" method signature we do not need to catch it here.
" BUT: Either catch or throw. Since we throw the exception class
" the caller of the method (= main program) must catch it.
ENDMETHOD. "divide
ENDCLASS. "lcl_myclass IMPLEMENTATION
DATA: go_error TYPE REF TO cx_root,
gd_msg TYPE bapi_msg.
DATA: go_myclass TYPE REF TO lcl_myclass,
gd_result TYPE i.
PARAMETER:
p_enum TYPE i DEFAULT '10',
p_denom TYPE i DEFAULT '1'.
START-OF-SELECTION.
TRY.
CALL METHOD lcl_myclass=>divide
EXPORTING
id_enumerator = p_enum
id_denominator = p_denom
RECEIVING
rd_result = gd_result.
WRITE: / p_enum, '/', p_denom, '=', gd_result.
CATCH cx_sy_zerodivide INTO go_error.
gd_msg = go_error->get_text( ).
MESSAGE gd_msg TYPE 'I'.
ENDTRY.
END-OF-SELECTION.
Regards
Uwe
04-10-2008 8:52 PM
Hello Ed
Using exception classes the rule is the same as in Java:
Either THROW or CATCH the exception.
To catch means to surround the problematic piece of coding using a TRY-CATCH-ENDTRY block.
To throw means to define the exception class as part of the method signature.
The sample report ZUS_SDN_EXCEPTION_IN_LOCCLASS demonstrates how to throw and catch the exception.
*&---------------------------------------------------------------------*
*& Report ZUS_SDN_EXCEPTION_IN_LOCCLASS
*&
*&---------------------------------------------------------------------*
*& Thread: Using exceptions in SE24 global class Builder
*& <a class="jive_macro jive_macro_thread" href="" __jive_macro_name="thread" modifiedtitle="true" __default_attr="817903"></a>
*&---------------------------------------------------------------------*
REPORT zus_sdn_exception_in_locclass.
*----------------------------------------------------------------------*
* CLASS lcl_myclass DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
divide
IMPORTING
id_enumerator TYPE i
id_denominator TYPE i
RETURNING
value(rd_result) TYPE i
RAISING
cx_sy_zerodivide.
ENDCLASS. "lcl_myclass DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_myclass IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass IMPLEMENTATION.
METHOD divide.
" raises division by zero error if id_denominator = 0
rd_result = id_enumerator / id_denominator.
" NOTE: since the exception class is defined within the
" method signature we do not need to catch it here.
" BUT: Either catch or throw. Since we throw the exception class
" the caller of the method (= main program) must catch it.
ENDMETHOD. "divide
ENDCLASS. "lcl_myclass IMPLEMENTATION
DATA: go_error TYPE REF TO cx_root,
gd_msg TYPE bapi_msg.
DATA: go_myclass TYPE REF TO lcl_myclass,
gd_result TYPE i.
PARAMETER:
p_enum TYPE i DEFAULT '10',
p_denom TYPE i DEFAULT '1'.
START-OF-SELECTION.
TRY.
CALL METHOD lcl_myclass=>divide
EXPORTING
id_enumerator = p_enum
id_denominator = p_denom
RECEIVING
rd_result = gd_result.
WRITE: / p_enum, '/', p_denom, '=', gd_result.
CATCH cx_sy_zerodivide INTO go_error.
gd_msg = go_error->get_text( ).
MESSAGE gd_msg TYPE 'I'.
ENDTRY.
END-OF-SELECTION.
Regards
Uwe
04-10-2008 9:09 PM
Thanks for replying Uwe. I'm afraid I'm not asking the question correctly.
What I want to have is an "IF" or "CASE" statement in my method.
When the IF test is false, I want to RAISE an exception similar to what you'd do in a function module.
04-10-2008 10:11 PM
Hello Ed
I have modified my sample report to show both ways: classical exceptions and exception classes. However, since exception classes are much more powerful I recommend to use them instead of classical exceptions.
Please note that you cannot mix classical exceptions with exception classes in the same class. Therefore I inactivated method DIVIDE_3.
*&---------------------------------------------------------------------*
*& Report ZUS_SDN_EXCEPTION_IN_LOCCLASS
*&
*&---------------------------------------------------------------------*
*& Thread: Using exceptions in SE24 global class Builder
*& <a class="jive_macro jive_macro_thread" href="" __jive_macro_name="thread" modifiedtitle="true" __default_attr="817903"></a>
*&---------------------------------------------------------------------*
REPORT zus_sdn_exception_in_locclass.
*----------------------------------------------------------------------*
* CLASS lcl_myclass DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
" use exception class
divide
IMPORTING
id_enumerator TYPE i
id_denominator TYPE i
RETURNING
value(rd_result) TYPE i
RAISING
cx_sy_zerodivide,
" use exception class
divide_2
IMPORTING
id_enumerator TYPE i
id_denominator TYPE i
RETURNING
value(rd_result) TYPE i
RAISING
cx_sy_zerodivide.
** " use classical exception
** divide_3
** IMPORTING
** id_enumerator TYPE i
** id_denominator TYPE i
** RETURNING
** value(rd_result) TYPE i
** EXCEPTIONS
** arithmetic_error.
ENDCLASS. "lcl_myclass DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_myclass IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass IMPLEMENTATION.
METHOD divide.
" raises division by zero error if id_denominator = 0
rd_result = id_enumerator / id_denominator.
" NOTE: since the exception class is defined within the
" method signature we do not need to catch it here.
" BUT: Either catch or throw. Since we throw the exception class
" the caller of the method (= main program) must catch it.
ENDMETHOD. "divide
METHOD divide_2.
IF ( id_denominator = 0 ).
RAISE EXCEPTION TYPE cx_sy_zerodivide
EXPORTING
textid = cx_sy_zerodivide=>cx_sy_arithmetic_error
operation = 'DIVIDE'.
ELSE.
rd_result = id_enumerator / id_denominator.
ENDIF.
ENDMETHOD. "divide_2
** METHOD divide_3.
** IF ( id_denominator = 0 ).
** RAISE EXCEPTION arithmetic_error.
** ELSE.
** rd_result = id_enumerator / id_denominator.
** ENDIF.
** ENDMETHOD. "divide_3
ENDCLASS. "lcl_myclass IMPLEMENTATION
DATA: go_error TYPE REF TO cx_root,
gd_msg TYPE bapi_msg.
DATA: go_myclass TYPE REF TO lcl_myclass,
gd_result TYPE i.
PARAMETER:
p_enum TYPE i DEFAULT '10',
p_denom TYPE i DEFAULT '1'.
START-OF-SELECTION.
** TRY.
** CALL METHOD lcl_myclass=>divide
** EXPORTING
** id_enumerator = p_enum
** id_denominator = p_denom
** RECEIVING
** rd_result = gd_result.
**
** WRITE: / p_enum, '/', p_denom, '=', gd_result.
**
** CATCH cx_sy_zerodivide INTO go_error.
** gd_msg = go_error->get_text( ).
** MESSAGE gd_msg TYPE 'I'.
** ENDTRY.
TRY.
CALL METHOD lcl_myclass=>divide_2
EXPORTING
id_enumerator = p_enum
id_denominator = p_denom
RECEIVING
rd_result = gd_result.
WRITE: / p_enum, '/', p_denom, '=', gd_result.
CATCH cx_sy_zerodivide INTO go_error.
gd_msg = go_error->get_text( ).
MESSAGE gd_msg TYPE 'I'.
ENDTRY.
** CALL METHOD lcl_myclass=>divide_3
** EXPORTING
** id_enumerator = p_enum
** id_denominator = p_denom
** RECEIVING
** rd_result = gd_result
** EXCEPTIONS
** arithmetic_error = 1.
** IF ( syst-subrc = 0 ).
** WRITE: / p_enum, '/', p_denom, '=', gd_result.
** ELSE.
** MESSAGE 'Arithmetic error' TYPE 'I'.
** ENDIF.
END-OF-SELECTION.
Regards
Uwe
04-10-2008 10:31 PM