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 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?
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.FileNotFoundException *Already tried this one
Wow, 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?
Editors Note: The WFExecutionException will catch any and all exceptions within a script. Use carefully.
Wouldn't it be handy to be able to test all 179 exception handlers in less than 5 seconds, and have a pretty report of which exceptions where thrown by 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 179 exceptions.
- The case script, which contains a recreation of your failing script steps, which the runner will run 179 times in less than 5 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 of execution*, 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 179 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 179 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.
The report now clearly shows us that none of the file exception handlers worked, even though the original error message displayed, clearly states: FileNotFoundException. It is the document exception handlers which we truly 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.
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. You wouldn't even need to debug the script at this point.
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.
**My testing shows that Firefox works best