The Editor and UCCX have changed since I originally wrote this document. I'm not sure if it was a coincidence, or Cisco actually accepted my challenge, but I do know that they never contacted me about this document, or my thoughts on Exception handling.
At any rate, in newer versions of the Editor, and thus UCCX (the specifics are unknown to me, but from my testing v10.6(1)SU1 is a rough gauge), the Exceptions have been significantly reduced from 179 to just 18. We've even gained the com.cisco.uccx.rest.client.RestClientException. Which means that 160 Exceptions were removed.
Therefore, if you try to use my attached scripts on one of these newer systems, only 17 of the Exceptions actually exist. In fact, if you try to run my script, it will fail. You will get a validation error in the Editor if you do Tools > Validate, stating certain Exceptions are no longer available to you. That list is:
So, I've modified the script to support the newer version, and have attached it to this document, along with the older script. I have also updated the text within this document to reflect this change as well.
If you haven't immediately thought "What happens to my system after I upgrade it, and I was using one of the exceptions previously supported, but now no longer supported?" Then I encourage you to go through all of your scripts, look at which exceptions you're referencing, and make sure they exist on v10.6+, else your scripts wont run.
If you were to reference a Document in the repository, which doesn't actually exist in the repository, what would happen to your script?
Without proper exception handling in your script, this would halt the execution of your script, and then proceed to play the "System Problems" message provided by the default script of the application.
I hear you asking, "Anthony, what can I do about this?"
Well, you can use the On Exception Goto step, which will catch the exception when it happens, preventing your script from halting.
The next challenge is navigating the 179 (or 18 if v10.6(1)SU1+) exceptions provided to you within the On Exception Goto step, to pick just the right one for the job. So, which one do you pick? If you look back at your error message, you see the FileNotFoundException being mentioned, so why not start with that?
Weird. That didn't work. Let's look back at the section where we found our FileNotFoundException, to see if there is something else we can try.
com.cisco.file.FileException com.cisco.file.FileExistException com.cisco.file.FileNotFoundException *Already tried this one com.cisco.file.InvalidFileClassException com.cisco.file.NoAvailableSpaceException com.cisco.file.impl.DbManagerException com.cisco.file.impl.FileIOException com.cisco.file.impl.FileMgrException com.cisco.file.impl.FileRemoteException com.cisco.file.impl.SyncFailedException
Ok, so, that's quite a few to choose from; however, it looks like the FileExistException might be a good second choice, let's try that and see if it works.
Ok, so, at this point, we could keep on guessing exceptions to use, and work our way through the list, eventually finding an exception to handle our exception. But, is the exception that you found really the best one for the job, or did you just settle on the first one that worked, due to frustration?
Note that the WFExecutionException will catch ANY and ALL exceptions within a script.
Wouldn't it be handy to be able to test all of the exception handlers in a matter of seconds, and have a nice looking report, showing which exceptions handlers caught your failing script step?
Now, you can! I have created a system that works on all licensing models of UCCX, which can catch and report on your failing script steps.
There are three scripts at work here:
The main script, which runs the exception runner and then uploads the report to the repository.
The runner script, which runs through the exception handling workflow for all exceptions.
The case script, which contains a recreation of your failing script steps, which the runner will run for each exception, in a matter of seconds.
Let's take a look at these three scripts in more details.
The Main Script
The main script is comprised of only two parts:
A subflow for calling the runner. This is done to bypass the slowness that is active debugging. If we were to active debug the runner, with its over 2,000 steps* for the 179 Exception version, and over 150 steps for the 18 Exception version, it would take a really long time for it to complete. And if you were to connect to the UCCX Engine over a VPN, it will take even longer!
Uploading the report to the repository with your authenticated user account's credentials.
To begin the process, you would have this script open in your editor, and simply begin the active debug process (F5 on your keyboard).
Once the main script finishes execution, your report will be uploaded in the repository and ready for your review. Navigate to the default language folder, and click the document icon to the left of the filename. This should open the report right in your browser.** We'll cover the report in a later section.
The Runner Script
The runner script is comprised of many moving parts. To summarize what it's doing: it uses the WFExecutionException handler as a safety net, as it attempts to catch the exception produced in the case script, with each of the exceptions available to you. Any further understanding of this script will be left as an exercise to the reader.
The Case Script
The case script should contain as few steps as possible to reproduce the failure you are experiencing in your production (or lab) script. For example, if I were facing a DocumentNotFound exception, I would not want to put in my IVR's greeting and menus. I would just slim down the testing to the document steps pertaining to the failure. Sometimes, that also means creating variables in this script; and feel free to do so. In fact, you could even create multiple case scripts, each with its own test case, and then repoint the subflow within the runner script, to pick which one you will run next.
Because you will not be using any exception handling within this script, the exception will flow upwards to the runner script for proper handling. Therefore, don't place any exception handling in here, or you will actually prevent the system from working as intended.
The report that is uploaded to the repository is an HTML document. You will need to view it in a web browser, and can do so by simply clicking on the icon to the left of the filename.
There are two major sections to the report:
The exception thrown by the case in semi-plain english
The list of all exception handlers, and a TRUE or FALSE value indicating whether or not the exception handler could handle the exception
Let's take a look at a report generated from our original FileNotFound exception above.
The Exception Thrown - Here you get an opportunity to read the error message thrown by your failing script step
The Results - Here you can quickly identify which exception handlers caught your exception.
Versions with 179 Exceptions
Version with 18 Exceptions
The report now clearly shows that, even though the original error message displayed: FileNotFoundException, it's the com.cisco.doc.Document Exception which we needed.
In conclusion, with this system in place, it would have taken me no time at all to figure out that the best exception handler to use would be: DocumentNotFoundException in the 179 Exception versions, and DocumentException in the 18 Exception versions.
I hear you asking, "But Anthony, what if my testing requires a phone call, or an HTTP trigger?"
Simply modify the case script to include steps such as: Accept, Play Prompt, Send HTTP Response, etc. Then create an Application/Trigger for you to kick off the process by calling into the Main script (which calls the runner+case script). You wouldn't even need to debug the script at this point. Just call it and then your report will be uploaded.
I challenge the community to take this system and improve upon it. I am a firm believer in collaboration, and that together we could make a better solution, than any one of us individually.
I also challenge Cisco to improve the exception handling facility within UCCX to be easier to use and more robust. As examples for Cisco: I would like to see more consistent error messages, and to be able to handle the ContactInactiveException on a per Contact basis.
*Because the runner executes over 2,000 steps, you will need to increase your Max Number of Executed Steps from 1,000 to 3,000 at a minimum. This requires you to restart the UCCX Engine, so plan for it a small outage to make this change.