Aspects of error handling
Error Handling refers to the anticipation, response, and recovery from error conditions. Writing VIs and subVIs that incorporate error handling is considered good form, not only to allow the user indication of abnormal software execution, but also to allow the software to make decisions based on the status of previous operations. Including error handling in your code assists in troubleshooting (debugging), modularity, and user friendliness. LV R&D architect Stephen Loftus-Mercer divides the topic of "error handling" into five (5) separate aspects in order to keep discussions on topic -- error handling is too broad for most conversations. The divisions below were introduced by Stephen Loftus-Mercer in several informal settings; LV R&D architect Darren Nattinger was the first to present them formally.
|Error Generation is the creation of an error cluster value at the point that something goes wrong in your LabVIEW code. Feature requests in this area cover readability of the error generation code on the diagram, simplicity of selecting the right error, and packaging valuable metadata with the error (such as the call chain, timestamp, or situation details).
||Errors may be emitted by both VIs and built-in nodes. When writing a VI that will emit a new error, there are two options:
|Error Propagation is the act of moving an error value through your LabVIEW code. When an error has been created it should be propagated or responded to (next section). Feature requests in this area include ways of aggregating multiple errors together, extending case structure behaviors, stopping loops/systems when errors occur, merging errors from parallel code, hiding error wires and creating some sort of automatic error propagation rules, etc.
||Propagation is accomplished using the error cluster and wiring from error inputs through the various code paths and out an error output. When propagating an error to a subVI, it is considered good practice to place error cluster input and output in the lower quadrants (error in on the left, and error out on the right). Multiple code/error paths can exist depending on data flow and parallelization.
The number one rule of error propagation is Don't Break the Error Chain! An error chain is the code path of the error from the point of generation through the VI hierarchy to the point of being handled by an Error Response, Error Display, and/or Error Logging. A break in the error chain occurs if even one VI in the hierarchy fails to propagate the error correctly. This causes an error from an upstream node to be lost and makes debugging difficult.
An error chain can be broken in three ways:
To attempt to avoid breaking the error chain, the following VI Analyzer test can be run:
|Error Response is what you do in your LabVIEW code when an error occurs and you analyze the error value within the code to respond in a certain way. Feature requests include ways to simplify coding the following behaviors:
See Stephen Loftus-Mercer's poster on Error Responses. The typical operation of a node is to execute only if no error comes in and may add its own outgoing error. Wrapping the entire code of a SubVI within a conditional case structure can make the SubVI act as a typical node (see Error Case Structure). However, if the code inside of the structure already operates according to a typical node then the case structure is redundant and keeps the compiler from some optimization it could do if the structure was not there.
Also, the developer could choose to enable Automatic Error Handling. However, automatic error handling assumes all error conditions are tested during development and requires special tooling (VI Scripting) to enable or disable the entire code base unless every output is wired by the time development is complete. The experts have strong opinions on whether automatic error handling should be used during development, although all agree that it should never occur in well-written released libraries and applications.
|Error Display is the act of displaying error information to the end user and/or code developer. Feature requests here include error localization (i.e., generating errors on French system but displaying them on an English system), meaningful translation for error codes, and rendering of the error metadata in a user-friendly form (color, pictures, tables, etc). Display also includes ways of providing advice on common causes of the error and how to fix the error.
||As of LabVIEW 2019, this is almost always accomplished with Simple Error Handler.vi or General Error Handler.vi.
The General Error Handler.vi includes an input parameter for the type of dialog, one option is "no dialog." It is recommended to use it instead of calling Error Code Database.vi. The primary reason for the recommendation is that the translation of error code cluster into human readable strings involves much more than just looking up text in the database. The source string itself may include information to override or extend the database, and the text in either the source string or the database may include formatting commands, such as HTML tags for bold face. Encoding information in the source string is a technique that will become more common in the future.
You may desire to display the text, fully formatted, in a string indicator of your own instead of in any dialog. Use the function of General Error Handler CORE.vi (found on the block diagram of General Error Handler.vi) to do this.
|Error Logging involves taking errors generated by LabVIEW code and logging them to file for later analysis. Error logging is similar to error display (above), but logging has some more interesting variations – recording in a human-readable form or is machine parseable, recording as localized or non-localized. Most importantly, whereas “no error” is not typically displayed to the user, it is critical that we be able to log “no error” so a log file can distinguish a successful run (“no error”) from an aborted/crashed run (one where the log file is empty). Feature requests in this area include mechanisms for making recorded errors readable and assistance debugging errors after the application finishes.||LabVIEW has no formal error log API because typically logging of errors needs to be folded into the general event logs of an API, which vary radically between applications. The error cluster can be translated into a loggable string by using the General Error Handler.vi, wiring "no dialog" to its input, and writing its string outputs to a log.
For more insight on why it is important to log "no error", please contemplate the 48th koan of Codeless Code: "The Protocols tell us of no fewer than Four Silences: the Silence Before Words, the Silence Between Words, the Silence of the Broken Pipe, and the Silence of Fallen Parcels. To the initiate they are as different as the characters for “end” 末 and “not yet” 未, although the outsider cannot tell one from the other."
- Error Handling Basics by NI.
- David Maidman’s Blog Post.
- SOLID Error Handling by Dmitry.
- Structured Error Handler Express VI by NI
- The Codeless Code, Koan 48
- Nattinger, Darren. "What to Expect When You're Expecting an Error" (NIWeek 2018)