Use Exceptions in ABAP-OO Workflow with custom text in workflow log
The new ABAP-Objects Workflow has taken over the existing concept of temporary and application exception, as it was used with BOR-based Workflows. It has been replaced by using a set of predefined exceptions within the method’s implementation.
The most commonly used exceptions are the following
|CX_BO_ERROR||Error||Application error occurred|
|CX_BO_TEMPORARY||Temporary||Temporary, recoverable error occured|
|CX_BO_ACTION_CANCELLED||Temporary||User has cancelled the processing|
You may also lookup for more exception, using the class builder and lookup the class hierarchy of CX_BO_TEMPORARY and CX_BO_APPLICATION, that are the two top-classes for the ABAP-OO Workflow Exceptions.
To use one of the given classes, you can just defined them in the “Exception” definition of the method.
The simplest way to make use of the feature that you’ve just created, is like this
RAISE EXCEPTION TYPE cx_bo_error.
With the BOR-based implementation, you had to define each exception with reference to a message-ID. This message-ID, including the four variables sy-msgv1,… were then displayed in the workflow log, and under the “Message” button of the workitem, which is a very nice feature, as you can provide more detailed information othen than just saying “There was some kind of error, and you could recover it, because it’s possibly temporary”.
And by raising the exception, you could pass more information to the workflow log.
exit_return 9001 ‘WACHF’. “User &1 is currently locking table XYZ
With the ABAP-OO implementation, this has become a bit more complicated, but once you’re through with it, it becomes fairly easy.
I do not repeat the common basis to define the outcomes in the step definition, how to create an ABAP-OO-Workflow class and so forth. Please read through the SCN, documentation or visit BIT611 for more information on that general topic.
Using custom text for OO-Workflow Exceptions
You can use the predefined classes and populate them with your own “text element” to have some more information displayed to the end user or the administration. The first – simplest – approach is, to create a new textID in the repository and use that, when raising the exception.
Create a new “concept” with transaction SOTR_EDIT.
|Maintenance screen of SOTR_EDIT||Call menu option Concept – Create|
Then fill in the screen for a new concept, which becomes the TEXTID later on. The field “Object Type” needs to be filled, but it’s pretty much useless here.
Please read through the documentation of the transaction to find out, how to translate the object into other languages, create a transport request, and so on.
After you’ve created the new concept, you’ll get a new GUID, which I would suggest to save it into a class constant.
To make use of this custom text within the exception handling of the workflow, you can simply use the following ABAP:
RAISE EXCEPTION TYPE cx_bo_temporary EXPORTING textID = ‘0050568015291ED2ABB3C86EAD8513B4’.
That’s it, already!
This will now look like this in the workflow log:
However, sometimes, that not just enough. … and the story continues …
Using custom texts with variables
To make text replacements for the text of the exception class, there’re two general approaches possible: Using a TEXTID based exception or a MESSAGE based exception. In the following section I will outline how to implement this with a TEXTID.
Create a new subclass of the exception type, you need, e.g. a temporary exception. So create a new class ZCX_TEMPORARY_WITH_TEXT, inheritingfrom CX_BO_TEMPORARY. Please be aware, that the exception class name must begin with ZCX…, YCX… or /<namespace>/CX…
After activation of the class, a new attribute is generated, which will be the default textID when the exception class is instantiated:
With some newer ECC-Release a new button appears here “Message Text” appears here, where you can assign a MESSAGE ID, and furthermore, thanks to the note from Mike (see comment section below), if you edit the long text here, you do not need to go to the SOTR_EDIT transaction.
Create new member attributes for that class, as you like. In this example: USERNAME. It must be the same naming as you’re using between the & and & of the text element.
The usage is now a bit different. So first of all, you need to list the exception in the method signature, of course:
And you cannot use the shortcut ABAP statement anymore, because you will need the following three steps:
– Instance a new exception class
– Assign the text elements before raising the exception
– Raise the exception object instance
“Special lock exception with text replacement on-the-fly
DATA: lx_temporary_locked TYPE REF TO ZCX_TEMPORARY_WITH_TEXT.
CREATE OBJECT lx_temporary_locked.
“All text elements embraced by & will be replaced by instance attributes
lx_temporary_locked->username = ‘WACHF’. “As an example
RAISE EXCEPTION lx_temporary_locked. “Object is temporary locked by user WACHF
or use this shortcut, as for each attribute an importing parameter will be generated for the CONSTRUCTOR, that can’t be changed otherwise. If you need to fill more tricky values, you need to use the proposed solution above.
RAISE EXCEPTION TYPE ZCX_TEMPORARY_WITH_TEXT EXPORTING username = ‘WACHF’.
And in the workflow log, it appears now like this:
And this is really an improvement, when comparing it with the default text:
It’s some work, but it’s very nice to use, when you got there.
Variant 2 – Using exception with message classes
Thanks to the comment of Jocelyn, I’ve added the part to populate a message-ID to an exception and raise that. However, I didn’t find any substance need to modify/enhance the exception’s constructor. It’s working without any coding (changes).
The existing class CX_BO_TEMPORARY is not an exception-class “with message class”, so you can’t use it directly, but you have to subtype it. So please subtype a new class, e.g. ZCX_TEMP_EXCEPTION_WITH_MESSAGE from the super exception class CX_BO_TEMPORARY.
Check the box “With Message Class” now.
After that, activate the new class. You don’t need to make any changes in the subtyped exception class.
If you found an exception list that already contains the superior exception class, i.e. CX_BO_TEMPORARY is already defined, you don’t need to add the new subtype to the exception list. It will be cast to the superior class.
There’s no additional coding except to correctly raise that message. In my example, I chose to set the message WF 015 “Cancelled by user”:
DATA: ls_message TYPE SCX_T100KEY,
lv_message_text(50) TYPE C. “Dummy message holder
MESSAGE I015(WF) INTO lv_message_text. “For where-used list and SY variables
ls_message-msgid = sy-msgid.
ls_message-msgno = sy-msgno.
ls_message-attr1 = sy-msgv1.
ls_message-attr2 = sy-msgv2.
ls_message-attr3 = sy-msgv3.
ls_message-attr4 = sy-msgv4.
RAISE EXCEPTION TYPE zcx_temporary_with_message EXPORTING textid = ls_message.
After that, you can find a temporary exception in your workflow log with the detailed message!
Any helpful comments are very welcome.
Please “rate” or “like” if you find this information useful.
SAP Business Workflow Senior-Expert
Update 1: Changed and reworked section Using custom texts with variables
Update 2: Changed a paragraph at the end, explaining that an existing CX_BO_TEMPORARY exception signature doesn’t need to be changed.
Update 3: Included comment from Mike regarding the message texting.