Skip to content

[Prefer RAISE EXCEPTION NEW to RAISE EXCEPTION TYPE] In defense of RAISE EXCEPTION TYPE #347

@marco-haupt

Description

@marco-haupt

Relevant sections of the style guide
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-raise-exception-new-to-raise-exception-type

Summary
The current style guide recommends using RAISE EXCEPTION NEW over RAISE EXCEPTION TYPE. However, this overlooks the significant difference in the instantiation of the exception object between these methods. This could potentially impact program behavior. I propose to reconsider this guideline.

Description
Greetings,

I'd like to propose a discussion regarding the existing guideline that favors RAISE EXCEPTION NEW over RAISE EXCEPTION TYPE. While I acknowledge that RAISE EXCEPTION NEW is indeed shorter and arguably easier to read, I believe that there is a significant aspect that has not been sufficiently addressed.

The key difference between these two methods lies in the instantiation of the exception object. RAISE EXCEPTION NEW instantiates an exception object immediately, whereas RAISE EXCEPTION TYPE leaves this to the handler. The latter only creates the exception object when a CATCH or CLEANUP clause uses the INTO addition. Here's an illustration:

try.
  raise exception NEW cx_sy_zerodivide( ). "is an explicit constructor expression
catch cx_sy_zerodivide.
endtry.

try.
  raise exception TYPE cx_sy_zerodivide. "does not execute the constructor -> no instantiation
catch cx_sy_zerodivide.
endtry.

try.
  raise exception TYPE cx_sy_zerodivide.
catch cx_sy_zerodivide INTO data(exception_object). "INTO causes the object to be instantiated here
endtry.

The reason for this difference can be traced back to the late inclusion of class-based exceptions in the language. To ensure competitiveness and allow for regression-free refactoring, the class-based exceptions were designed to be as efficient as their predecessors. Since object creation can be relatively time-consuming and many exceptions can be handled without creating objects, it was deemed prudent to only create objects when absolutely necessary. The RAISE EXCEPTION variant (without TYPE) is meant to pass on existing exceptions to the next program level(s).

If exceptions are only used in exceptional situations and not as a rule, the performance may be negligible. But this distinction is of crucial importance if exception constructors are not free of side effects. Although best practices dictate that constructors should not have side effects, this cannot always be guaranteed. Therefore, if not properly understood, the substitution of RAISE EXCEPTION TYPE with RAISE EXCEPTION NEW could potentially modify the behavior of the program.

Personally, I would always advise using RAISE EXCEPTION TYPE due to its superior capabilities. However, if specifying EXPORTING is considered detrimental to readability, the guide should at least caution users about this potential pitfall.

I'm eager to hear your thoughts on this suggestion and hope to foster a productive dialogue that will enhance our coding practices.

Examples
Constructors should never have side effects! Please do not imitate! I only provide the following example to illustrate my point.

class cx_custom_error definition inheriting from cx_no_check.
  public section.
    methods constructor.
endclass.

class cx_custom_error implementation.
  method constructor.
    super->constructor( ).
    raise shortdump type cx_sy_no_handler.
  endmethod.
endclass.

start-of-selection.
  "This try block will be completed successfully.
  try.
    raise exception TYPE cx_custom_error.
  catch cx_custom_error.
  endtry.

  "This try block will end in a runtime error.
  try.
    raise exception NEW cx_custom_error( ).
  catch cx_custom_error.
  endtry.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Adjustment Of RuleThe issue or PR proposes an adjustment of a rule or set of rulesclean-abap

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions