User exit for production order confirmation in CO11N? - abap

I've watched quite a few videos on YouTube and have a basic understanding of how to find user-exits (enhancements?) and implement them. However when I try to replicate what I've seen it doesn't appear to be working.
I'm looking to create a user-exit that would execute when a production order has been confirmed (closed/finished) via CO11N. Someone suggested that I put in a line of code "BREAK username." So that I could verify that my code was firing. Nothing breaks. I've tried putting in a message from code found on the internet
MESSAGE s208(00) WITH 'TEST'.
No message is shown. I've activated the include and the project. I've tried different exits/includes and no matter what I do, nothing seems to break or show a message.
Is there something simple I'm missing? I've tried CONFPI05 and CONFPM05.

CONFPI05 is for process orders. CONFPM05 is for plant maintenance orders. First you need to check which kind of order you use. I assume you use production orders. You should check User-Exit CONFPP05 than.
Anyway, I would recommend using BAdI WORKORDER_CONFIRM. Within this BAdI there are methods available where you can raise an error message.
From the BAdI documentation:
Note that in the methods, no system messages may be sent. The only
exceptions are the AT_SAVE and AT_CANCEL_CHECK methods. Within these
methods, a system message may be issued, but only if you trigger the
exception ERROR_WITH_MESSAGE (for AT_SAVE method) or NOT_ALLOWED (for
AT_CANCEL_CHECK method) at the same time.
Note also that within the methods, the "commit work" instruction may
not be carried out because this would lead to incorrect data in the
database.
I strongly recommend not to use MESSAGE statement in any User-Exit or BAdI implementation. The MESSAGE statement will implicit call a COMMIT WORK which could cause database inconsistencies (happens very often by the way).
One additional note. You should check using Checkpoint Groups instead of using BREAK-POINT or BREAK username directly.

I checked the documentation:
CONFPI05 to update your own data after saving the confirmation
In another documentation I found another warning:
In this customer enhancement it is strictly forbidden to send error messages or other messages because otherwise there is the danger that data will be inconsistent. SAP cannot be held responsible for this!!
This sounds like changes in update task. By default breakpoints in update task are not enabled.
Should your code be processed after you pushed save?
If yes, what you can try:
Set anywhere a breakpoint. Or try /h during data insertion.
In debug screen activate the update debugging:
Continue the process with F8.
Hopefully you stop at your break-point.

Related

Why in mulesoft "on Error Propagate" rethrows the same error?

I am new to mulesoft and while studing it i strugle to understand why on module "onErrorPropagate" the error is being rethrown after executing the scope.
can you explain the benefits?
An on-error-propagate will rollback any transactions, execute, and use that result to rethrow the existing error––meaning its owner will be considered as “failing.”
The best use is in a layered system, to allow each layer to do its own small part of an error response.
If you are familiar with Java you can think of it as catching the exception and re-throwing it. For example, sometimes you want to do something with the error yourself, but still want to propagate it upwards for higher levels to deal with.
You could add logging in a specific flow for the error but then leave it to the parent flows to actually deal with the exception.
The "onErrorPropagate" propagates (rethrows) the error to the parent flow (or the global error handler if it's already reached the main flow).
This can be usefull in a few cases.
Say you have some flow specific error handling (e.g. if something goes wrong, set a default payload).
Then you propagate this error to the next level where you have your Global error handler that, say, stores some info in a QA database.
You don't want to have that database connector in every single error handler.
In this way you can achieve a 'java inherritance' like structure, for your errors.
Side note: if you want your error to only be handled and do nothing further, you can use "onErrorContinue"

Check original language of repository objects at creation?

In our company, repository objects must be created with original language EN.
Is there a way to check the logon language in case of creating a new object in the ABAP repository?
Desired behaviour:
SE80 - Create program/class/data element/table/....
==> user exit/badi checks the logon language. When it is not 'EN', the creation will be refused.
regards,
Umar Abdullah
I know there is a exit for this but I haven't remember exact name. You can use general purpose for finding exit. Go to SE24 and open CL_EXITHANDLER class, find GET_INSTANCE method and add break point. Then start creating item, it will pause on debugger multiple times, try to find suitable one.
As #mkysoft suggested, you may implement a check in the BAdI CTS_REQUEST_CHECK, method CHECK_BEFORE_ADD_OBJECTS, which is invoked when the object is about to be attached to a transport request. Raise the exception CANCEL to make the attachment fail (and so the object is not created too).
EDIT: sorry, ignore my answer, "this method is NOT released for Customer usage" as said in note 2150125 - Method CHECK_BEFORE_ADD_OBJECTS not triggered
DISCLAIMER: THE METHOD DESCRIBED HERE IS ABSOLUTELY NOT RECOMMENDED.
As correctly pointed out by the other members there is no standard and customer-exposed method to achieve your requirement, but if you absolutely must enable this check during creation you can use the below method. As well as the previously offered to you, it also involves modification of SAP standard.
There is a system BAdi CTS_TADIR_SUBSCREEN that is located inside enhancement point CTS_ES_TADIR_POPUP. They are SAP internal and not released for customer usage, so do this at your own risk.
Implementation procedure:
Step 0. First thing you need to change is a SAP internal usage flag, for which you need Object Access key which can be obtained from SAP or from SAP partner that made the implementation in your org. In virgin state this BAdi throws the error if you try to implement it
So hereinafter we assume that you already ticked off this checkbox in BAdi settings
Step 1.
In order to implement the BAdi one need to implement enhancement spot prior to that. This is the most complicated part, because despite we disabled internality flag the SAP-namespaced enhancements must be stored only in SAP-namespaced objects. By SAP namespace I mean non-Z, non-Y and non-T (Test). This means to implement this enhancement, besides modifying the enhancement definition, one need to create, for example, CTS_ES_TADIR named enh.impl., and save it to non-Z package, which you also need to create. Your enhancement implementations selector should look somehow like this
On the above screen only the second will work, all the rest Z will not.
Every non-Z object need Object Access Key, remember? Too bad. But just to show the proof-of-concept, I will proceed.
Step 2. After you created the enh. implementation in SAP-namespace it will propose you to create the BAdi implementation. The same principle applies here: only SAP-namespaced container for SAP-namespaced objects, hence CTS_TADIR_SUBSCREEN should have implementing class for example CL_TADIR_SUBSCREEN. During the creation of enhancement you will see many warnings
but finally you should have something like this, where all system-named objects are created and the enhancement/BAdi is activated.
Step 3. In order to get the BAdi working we need to enable this subscreen processing
during the playing with enhancement I found out that BAdi class is not being triggered standalone, without screen events not enhanced, so to make it work you need to touch a screen enhancement for screen 100
If you do not wanna modify screen elements logic, just put the dummy enhancement in SHOW_TADIR dialog module in the end of the include LSTRDO18
PROCESS BEFORE OUTPUT.
MODULE SHOW_TADIR. "<-- create the dummy enhancement here
CALL SUBSCREEN subs_info INCLUDING gv_badi_prog gv_badi_dynnr.
for example declaration statement like I did
Step 4. Activate your created BAdi class and put the necessary logic there. I wasn't able to trigger method GET_DATA_FROM_SCREEN, but PUT_DATA_TO_SCREEN worked fine
If we put this simple processing for your requirement
METHOD cts_if_tadir_subscreen~get_data_from_screen.
IF object_data-l_mstlang <> 'E'.
MESSAGE 'Objects in non-English languages are not allowed!' TYPE 'A'.
ENDIF.
ENDMETHOD.
it will not allow creating objects in languages other than English.
The check in method get_data_from_screen is being done before showing the screen so language is determined from system logon settings. If to play more with this BAdi, I suppose the method GET_DATA_FROM_SCREEN can also be enabled, which will make it possible to check user input, i.e. the case when the user gonna change the default language.

How can I display exception messages from custom functoid errors in the BizTalk Administration Console?

My goal is to influence the error descriptions that appear in BizTalk Administration Console in the Error Information tab of suspended instance windows, after errors occur in my custom functoids. If possible, I would also like the ErrorReport.Description promoted property to display this error description on the failed message.
I've read everything I can find about custom functoid development, but I can't find much about error handling within them. In particular, whenever my functoids throw exceptions, I see the boilerplate "Exception has been thrown at the target of an invocation" message that occurs whenever exceptions occur through reflection, rather than the message on the exception itself.
I had hoped to find something within the BaseFunctoid class framework that would allow me to submit an error string, so as to traverse the reflection boundary. Is there some way to pass error information from within a custom functoid, such that the BizTalk Administration Console will display it?
If I emulate the approach taken by DatabaseLookupFunctoid and DatabaseErrorExtractFunctoid, is there some way I can fail the map with the extracted error, rather than mapping it to a field on the destination schema as is shown in its examples?
The simplest way to do this is using custom C#, writing something like this in your code:
System.Diagnostics.EventLog.WriteEntry("EVENT_LOG_SOURCE", "Error message...", System.Diagnostics.EventLogEntryType.Error);
As Johns-305 mentions, you need to make sure your event source is registered (e.g. System.Diagnostics.EventLog.CreateEventSource("EVENT_LOG_SOURCE", "Application") - but this should really be done as part of your installation steps with an EventLogInstaller or some kind of script to set up the environment). It's certainly true that error handling in BizTalk is just .NET error handling, but one thing to keep in mind is that maps are actually executing as XSLT, and the context in which their executing can have a major impact on how exceptions and errors will be handled, particularly unhandled exceptions.
Orchestrations
If you're executing a transform in an orchestration that has exception handling in it, the exception thrown will be handled and may even fall into additional logging you have in the orchestration - in other words, executing a throw from a C# functiod will work the way you'd think it would work elsewhere in C#. However, I try to avoid this since you never know if a map will at some point be used else where and because exception handling in XSLT doesn't always work the way you'd think (see below).
Send/Receive Ports
Unfortunately, if you're executing a map on a send or receive port and throw an exception within it, you will almost definitely get very unhelpful error message in the event log and a suspended instance in the group hub. There is no easy, straightforward way to simple "cancel" a transform - XSLT 1.0 doesn't have any specified way of doing that (see for example Throwing an exception from XSLT). That leaves you with outputting an error string to a particular node in the output (and/or to the EventLog), or writing lots of completely custom XSLT to try to validate input, or designing your schemas properly and using a validating component where necessary. For example, if you have a node that must match a particular regex, or should never be empty, or should never repeat more than X times, make sure you set those restrictions on the schema and then make sure you pass it through the XmlValidator or similar before attempting to map.
The simplest answer is, you just do.
Keep in mind, there is nothing special at all about error handling in BizTalk apps, it's just regular plain old .Net error handling.
So, what you do is catch the error in you code, write the details to the Windows Event Log (be sure to create a custom Event Source) and...that's it. That is all I do. I don't worry about what appear in BT Admin specifically.strong text

When programming, do you show all errors as message boxes or do you put them in a log file

I am trying to develop a standard when I code applications.
I was curious as to what other developers did when it comes to sql errors or general program errors. Do you output the error to the screen, write to a log file, or something else?
It really depends on the severity of the error.
Is it a show stopper?
Can the software automatically retry and get away with no message?
Can it be ignored?
You can log every exception, or just certain ones, or none. I have a custom Exception class which logs every exception created (of that type).
I have an unhandled exception handler which emails me when there is one.
I'd only send a message to the user when it will change the way the application works from the user's point of view.
Your question is a bit subjective and you would get opinion-based answers if the entire community bothered to answer.
If the error is relevant and important to the user (e.g.: invalid username/password) display it to the user using a message box.
If the error is relevant to the developer, or can be used in the debugging process, use a log or a console output.
The trick is to identify which and how the errors should be displayed to the user. You don't want to bombard the user with exceptions and complicated errors on which the user has no idea on how to act upon.

Error handling: show error message or not?

Generally, in software design, which of the options below is preferred when there is a problem or error with a resource such as a database or file?
Show an error message
Do not show an error message and act as though the resource was empty (eg. do not populate a GUI component)]
For example, should the user see an empty DataGrid following which they complain, or should there be an error message? Which is better?
I don't see this as an either/or. Also, we need to consider all "users" of the system.
First consider the UI. Let's consider a contrived general case: you are populating a UI by calling a service which in turn uses a couple of of databases (for example a "current data" and an "historic data") database.
There are at least these possibilities:
It all works, data is retrieved
It all works but as it happens there's no data for this particular query
Can't reach the service
Service is invoked, but one database is down
Service is invoked, but both databases are down
Then also consider your application's semantics. Can your applciation procede in a "degraded" mode if all the data cannot be retrieved? For example, we can't query the history but that doesn't stop us creating a new item.,
Now also consider the roles here. There's the person using the UI, there's also support and maintenance people who need to know about and fix problems.
My general rules:
First Failure Data capture: Whichever component first detects an error should log it in some detail. So, service up, database down the service should log the problem. Service down, the UI should log the problem. This log should be a technical record targeting the support roles.
UIs should be tolerant: if at all possible run in a degraded mode. So if the service is down but (for example) local working is possible put up an empty screen and continue. BUT ...
Always indicate a problem: The "no data for this query" and "databases unavailable" cases may both result in an empty screen. The user needs to know the status of the display, is it showing complete information, partial information (eg. because one DB is down) or is no information available (eg. service or both dbs down). So have a "Status" field somewhere on the screen. Giving messages such as
Historica Data not currently available
or
There are problems retrieveing
information, if these persist please
contact support ...
There are some pitfalls to each of the options
Showing error message
This is specially helpful when your application is in testing stage or public testing. Also when clients meets an error, he or she can copy down the details and forward to you.
However sometimes this error message gets very ugly (call stacks and so on - remember ASP.NET?) and it becomes so large that it becomes difficult for clients to copy down the details.
Do not show error message and act as though nothing happened =)
This is useful when you don't want error messages to cog up your software UI design. But be reminded that it becomes difficult and further error prone when clients can't differentiate between an actual error, or really nothing on the GUI. The error stays there and nothing gets fixed.
My stand
Get the best of both worlds. In fact most modern applications how have a very good error handling process. I'll take the example of Mozilla Firefox 3.
A deadly error occurred and Firefox crashes
Error is captured and stored into a file as a form of error report
Error Reporting Application pops up apologizing to the user
Ask the user if the user want to send the error report to the software dev team
Then ask the user if want to restart the application
Or if the error is a warning or of lesser severity:
Show a simple error code and tell the user that there's the error with that action. Something like: "Error 123 at RequestSalary() Line 2"
The practice I usualy use is:
If the error didn't happen due to user error, then you should try to handle the error quietly.
If the error occurred because of some external problem (such as no internet connection) then you should alert the user.
IMO you should show a message (albeit a user friendly one and not something like "java.io.IOException: Connection timed out".) You could have a message box telling the user that an error occured while getting the data and provide helpful tips like: Trying after some time, check network cable, etc.
Also allow user to report that error to you (error reporting build into the app) that will send you the actual error and stack trace.