Runtime Error Handling in ProcScript
As a developer, you need to ensure that you anticipate and mitigate errors that may occur when running the application. The cause of an error could be a programming mistake, a configuration error in the runtime environment, or it could be a technical failure at runtime.
A runtime error can occur for many reasons. For example, component activation may fail with error -50
if Uniface cannot find the component. It could be missing or it could be because of a typo in the component name. In either case, you want to be informed of the error as soon as possible and not continue with normal code execution.
If the code does nothing about the error, the application may end up in a non-controlled state, which increases the risk of (unnoticed) data corruption and/or security vulnerabilities.
It is therefore important to deal with errors immediately, or prevent normal code execution from continuing. Uniface provides two approaches to error handling:
- Exception handling enables you to handle expected errors using try-catch blocks, and throw uncaught exceptions to the calling module. If the exception is not caught anywhere in the call stack, code execution stops and Uniface exits with a description of the uncaught exception.
This approach has several advantages:
- Coding errors are made visible quickly.
- Anticipated errors are explicitly coded using
try-catch
blocks, making the code more self-describing, readable, and maintainable. - Tracing the source of an error is easier because there is a call stack that records where the error occurred.
- Normal code flow does not require code for error checking as this is done implicitly by Uniface. This has a positive impact on performance and again makes your code more readable and maintainable.
For more information, see Exception Handling.
- Classic error handling requires you to explicitly check for and handle anticipated errors using $procerror and $procerrorcontext immediately after every significant ProcScript instruction. If an error is not handled, it is ignored and code execution continues.
This approach has some disadvantages:
- It is error-prone because it relies on humans to anticipate on all possible error conditions and implement adequate error handling wherever it is required.
- It is difficult to debug and trace exceptions back to their root cause because $procerror and $procerrorcontext are overwritten with each error that occurs as code execution continues.
- It requires more error-handling code and processing.
- Every check for errors is always executed, even for normal code flow. This can have a negative impact on performance.
For more information, see Classic Error Handling.
For existing applications, the two approaches can exist side-by-side so that you can gradually introduce exception handling without having to refactor your whole application.