Can I pass a message in a variable when raising an exception - abap

I am trying to pass a message in a variable when raising an exception.
For example:
DATA: lv_msg TYPE string,
lv_filename TYPE string VALUE 'file'.
CASE sy-subrc.
WHEN 0.
"No error go on
WHEN 1.
MESSAGE e001(cl_error) WITH lv_filename INTO lv_msg.
WHEN 2.
MESSAGE e002(cl_error) WITH lv_filename INTO lv_msg.
WHEN 3.
MESSAGE e003(cl_error) WITH lv_filename INTO lv_msg.
WHEN OTHERS.
MESSAGE e004(cl_error) WITH lv_filename INTO lv_msg.
ENDCASE.
RAISE EXCEPTION TYPE cl_base MESSAGE lv_msg.
This does not work.
I know i can achieve that using:
MESSAGE ID sy-msgid            
TYPE   sy-msgty            
NUMBER sy-msgno            
WITH   sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
But this does not solve my problem, because i am trying to use a message class.
So my question is, if passing the message trough a variable is possible?

Related

SAPGUI not displaying long_text or text for unhandled custom exceptions

In SAP NetWeaver 7.52 I created an ABAP classed based exception that works fine while executing within a try catch clause in the report/program. But the custom message is not displayed in SAPGUI when the exception is not handled by a try catch clause.
What I'm looking for is that when no try catch is defined the exporting message used at the moment of the raise statements is shown in the "UNCAUGHT_EXCEPTION". I have tried redefining the get_text( ) and get_longtext( ) methods. But the ABAP Run time error does not give any useful information to the developer about the cause (which is stored in the "attr_message" attribute of the exception).
When using the "try catch" the message can be retrieved without problems, but the idea is that SAPGUI presents the developer the right message in the "ABAP Runtime Error" report.
zcx_adk_exception.abap
"! Base exception for all ABAP Development Kit (ADK) exceptions
class zcx_adk_exception definition public create public inheriting from cx_dynamic_check.
public section.
"! Initializes the exception message
"! #parameter message | Message related to the reason of the exception
methods constructor
importing value(message) type zadk_str optional.
"! Returns the message associated to the exception
methods get_message
returning value(result) type zadk_str.
methods if_message~get_text redefinition.
methods if_message~get_longtext redefinition.
private section.
data attr_message type zadk_str value ''.
endclass.
class zcx_adk_exception implementation.
method constructor ##ADT_SUPPRESS_GENERATION.
super->constructor( ).
if message is not initial.
me->attr_message = message.
endif.
endmethod.
method get_message.
result = me->attr_message.
endmethod.
method if_message~get_text.
result = me->get_message( ).
endmethod.
method if_message~get_longtext.
result = me->get_message( ).
endmethod.
endclass.
What works fine:
try.
raise exception type zcx_adk_exception exporting message = 'Base_Exception_Error'.
catch zcx_adk_exception into data(ex).
write: / 'Example 1:', ex->get_message( ).
write: / 'Example 2:', ex->get_text( ).
write: / 'Example 2:', ex->get_longtext( ).
endtry.
And the output is this:
What does not work:
" Not Catching the exception
raise exception type zcx_adk_exception exporting message = 'Base_Exception_Error'.
This results in the following message being displayed instead
Following the previously proposed idea of using a message I came up with the following code that allows the exception to be raised with a message. This allows the exception to show the right message when called within a "try catch" block and display a useful message in the "Error analysis" section of the dump generated by SAPGUI.
Solution:
"! Program to test functionalities and utilities
REPORT zsandbox_tests.
" Exception Class
CLASS lcl_exception DEFINITION INHERITING FROM cx_dynamic_check.
PUBLIC SECTION.
INTERFACES if_t100_dyn_msg.
METHODS if_message~get_text REDEFINITION.
METHODS constructor
IMPORTING VALUE(message) TYPE string.
PRIVATE SECTION.
DATA attr_message TYPE string VALUE ''.
ENDCLASS.
CLASS lcl_exception IMPLEMENTATION.
METHOD if_message~get_text.
result = attr_message.
ENDMETHOD.
METHOD constructor.
super->constructor( ).
me->attr_message = message.
ENDMETHOD.
ENDCLASS.
" Class that raises the exception
CLASS lcl_main DEFINITION.
PUBLIC SECTION.
CLASS-METHODS main RAISING lcl_exception.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
DATA raise_message TYPE string VALUE 'Custom Message for the Exception'.
RAISE EXCEPTION TYPE lcl_exception
MESSAGE e000(lcl_exception) WITH raise_message '' '' '' " The if_t100_dyn_msg supports 4 attributes: V1, V2, V3 and V4 but I only use the first one
EXPORTING message = raise_message.
ENDMETHOD.
ENDCLASS.
" Call to Main Method
START-OF-SELECTION.
TRY.
lcl_main=>main( ).
CATCH lcl_exception INTO DATA(ex).
WRITE ex->get_text( ).
ENDTRY.
This generates the following output:
When no try catch is used:
" Call to Main Method
start-of-selection.
lcl_main=>main( ).
This is the output:
TL;DR : SAP did not plan to permit the customization of a short dump by the developer.
A "short dump" is a report which is generated by the ABAP kernel when an unexpected error occurs in an ABAP program, i.e. an error due to a bug in the program (usually an uncaught exception, or non-catchable errors) or to a system failure (input/output resources, memory resources, etc.)
It's intended to help the developer analyze the cause of the error and correct it.
It's not intended to be generated on purpose, except in a situation that the developer has made theoretically impossible, but actually happens, and which is thought to require many information to analyze if it happens, hence a short dump.
If it's really your intention to generate a short dump with a message, for some purpose, there are two ways:
MESSAGE 'message text' TYPE 'X'. (often used in standard SAP programs, especially in update function modules)
RAISE SHORTDUMP ... or ... THEN THROW SHORTDUMP ... in conditional expression. Both exist since ABAP 7.53. For instance RAISE SHORTDUMP TYPE zcx_adk_exception EXPORTING message = 'Base_Exception_Error'.
The short dump will contain the message text in the Analysis section.

Access shadowed variable from subroutine?

How to call a shadowed variable from subroutine?
Below is code sample, where I do want to print shadowed variable value:
data i type i value 13.
perform _form.
form _form.
data i like i.
i = 17.
" write shadowed i value here
endform.
There is a possibility to do it dynamically with ASSIGN ('(PROGRAMM)VARIABLE') TO FIELD-SYMBOL(<lv_fs>).
Here's an example.
REPORT zz_test.
DATA i TYPE i VALUE 13.
PERFORM _form.
FORM _form.
FIELD-SYMBOLS <lv_shadow> TYPE i.
DATA i LIKE i.
i = 17.
" write shadowed i value here
ASSIGN ('(ZZ_TEST)I') TO <lv_shadow> CASTING.
IF <lv_shadow> IS ASSIGNED.
WRITE <lv_shadow>.
ENDIF.
ENDFORM.

error in LinkingSetRelation - Invalid cast ... as object

I have the following error when I try to save a form with linkingsetrelation field:
Invalid cast exception while trying to set the value of ProductId field on ProductRow as object.
What can cause this error? any idea?
Thx
found it.... fields must be Int32, cannot use Int64!

Type mismatch. The return type 'Void' of best-match method on type is not compatible with the 'Result' argument supplied to InvokeMethod

Getting Error while Invoking Workflow Activity in WCF Services
Type mismatch. The return type 'Void' of best-match method 'Mailsend' on type 'BusinessClass' is not compatible with the 'Result' argument supplied to InvokeMethod 'JobNotification', which expects return values of type 'String'.
It solved while defining Activity inArugment type of all the associated parameters.

How to find which was the wrong message in a Message Not Understood message?

I want to find the name of the message that triggered the MNU , how do I do that ?
For example if I do
Transcript explode .
This will trigger a MNU because method explode does not exist but how do I find that the name of the message that triggered MNU is "explode" ?
Try this:
[Transcript explode]
on: MessageNotUnderstood
do: [:ex| ex message selector]
The exception's message is an instance of Message. It understands selector arguments etc.
Remember that the exception is an epiphenomenon. The VM actually sends doesNotUnderstand: aMessage when a message is not understood, and the doesNotUnderstand: method in Object raises the exception. The argument to doesNotUnderstand: is a message, and is of curse the same as that in the exception. That means you can implement your own doesNotUnderstand: message in your own class if you have special requirements.
If I DoIt that, I get a debugger. The title there is
MessageNotUnderstood: ThreadSafeTranscript>>explode
When I select the first element, I get to see the doesNotUnderstand: aMessage, where aMessage is the message