I can’t create anything under the webMethods tag, can someone move this to the correct forum?
Product/components used and version/fix level:
wM 10.5
Detailed explanation of the problem:
Hello, I have recently noticed a problem with exception handling using the native TRY/CATCH/FINALLY blocks.
In our solution, we use custom logging to a local DB which involves a document being kept in the pipeline.
When using the Sequence try/catch, the pipeline inside the try block is kept when an exception is raised from any lower-level flows and is available in the catch sequence.
However, when using the native Try/Catch, if an exception is raised, the pipeline that will be kept when I enter the catch block is the pipeline of the flow where the exception was raised.
Example:
Flow1:
TRY:
LogStart(Create logging document)
Map(A mapping step with a transformer)
Flow2
Flow3
LogSuccess(Receive document and save as success in DB)
CATCH:
getLastError
LogFailure(Receive document and save as failure in DB)
LogStart - custom flow service: creates the document
LogSuccess - custom flow service: takes the document and saves it as success in the DB
LogFailure - custom flow service: takes the document and saves it as failure in the DB
Flow3 and Flow4 are flow services with something that can fail inside.
Case 1: The map step in Flow1 fails - The log document stays in the pipeline when entering the catch step. LogFailure ends with success.
Case 2: Some step in Flow3 or Flow4 fails.
As none of these flows take the log document as input, it isn’t in the pipeline. When the exception is raised, LogFailure fails, because it needs the document that was created in the TRY step of Flow1.
When using sequences, this would not be a problem, because the variables from the top-level flow are preserved.
My question is:
Is it possible to retrieve the pipeline from the top-level service in the catch block?
The pipeline inside the service that raised the exception is already available with getLastError, so I don’t see the point of this behavior in the native TRY/CATCH.
I have not been working with Adabas or Natural, but with the wM Suite.
Just one point about your code which caught my attention:
Anything defined in the TRY-block will stay in the TRY-block, except for the case that an error is thrown, which is picked up in the getLastError step.
Can you check what happens when you call LogStart() before the TRY-block is entered?
This should preserve the created document even in the CATCH-block additionally to the informations grepped by the getLastError step.
If neccessary, you can drop the created document in the first step which is executed after either the TRY-block or the CATCH-block has been finished.
You need IS core audit DB function to be set for this and it can log each and every object in the pipeline. You can use MWS to review the failed service requests, to update them, and them resubmit them later if you enable this functionality.
Yes, that is an unfortunate behavior of the new TRY-CATCH construct. As a result, some of us have opted to stick with the traditional SEQUENCE-based try-catch. I think that may be your best bet as well. Here’s a thread where this issue was discussed a bit:
We have tried calling logStart() before the TRY block, but unfortunately, it does not work.
All we have available inside the CATCH block is the pipeline at the moment of the error.
This behavior doesn’t make sense, honestly. We would love for IBM to issue a fix on this. Variables defined in the outer scope should definitely be available.
Thanks for referring me to the other thread.
We are talking to SAG/IBM about this, they have supplied workarounds that don’t really work.
For now, we have three choices.
Explicitly declaring the log document as an input, including it in the clearPipeline preserve list, or having the sub-flow inside a MAP step as a transformer.
The first two have two problems, variable conflicts and the document not being a real input.
Calling the sub-flow as a transformer keeps the scopes intact, but it destroys readability and is a bit more annoying to debug.
I’ll update the thread if we get a satisfactory answer meanwhile.
From what I read and understand, it was an attempt to make try/catch an explicit construct within the FLOW language and an attempt to behave more like Java exceptions, supporting differing catch handling based upon the type of exception.
I would offer that you have 4 – the 4th being switching back to using SEQUENCE.
As noted in the thread that @Percio_Castro1 referenced, we decided to avoid the “new” try/catch and stayed with SEQUENCES. We found we rarely need finally, and when we do (file closing) it is relatively easy to accommodate.
Side note: clearPipeline is something that should be avoided, IMO.
Absolutely! When the service handles data properly (i.e. drop fields asap), there is simply no need for it. And it can cause issues with test automation and mocking.
In some contexts, I find it risky not to call clearPipeline in a finally block at the end of flow service (preserving only the explicit output parameters). E.g. in a REST API service, abnormal termination can leak sensitive data to the client. Likewise, sometimes elements will appear on the pipeline at runtime that are not even visible at design time
webMethods 11.1 apparently has a fix for this. From the release notes
"Strict Top-Level Service Output Control the output pipeline for any top-level service to return only the values specified by the service output. This ensures that all other values are removed, helping to prevent sensitive information from being inadvertently leaked through the output pipeline."
Agreed that it is useful in specific scenarios. We’ve all encountered “pipeline littterbugs” including some built-in services.
One of the techniques from “Writing Solid Code” is “step through your code.” This approach can help identify litterbugs – “where did that var come from?” When litter is found, it can be explicitly dropped. We’ve done that a couple of times over the years.
Stepping through code sounds very time-consuming. The chapter on this topic in the book explains that while it does indeed take time, in the scheme of things it is a fraction of the time it takes to write the code. “Don’t wait until you have a bug to step through your code.”
Of course there are still the cases where, even after stepping through code, other changes and IS updates can introduce new pipeline litter. The 11.1 feature to enable strict top-level output sounds like a great additional tool in the toolbox to help with this.
We finally got an update from IBM, saying:
“Development team is working on a way to ensure pipeline restore works with TryCatch similar to the behavior seen in Sequence.”
Hoping that this gets solved soon.