Jump to content

Aspects of error handling: Difference between revisions

From LabVIEW Wiki
No edit summary
m Add to Error Handling category
 
(23 intermediate revisions by 7 users not shown)
Line 1: Line 1:
{{Template:ActiveDiscuss}}
{{TOCnestright}}
Every LabVIEW programmer has their own approach to handling errorsIn fact, those with multiple personalities probably have several different approaches to handling errors. As an example, consider the producer-consumer diagram shown in '''Figure 8'''.
'''Error Handling''' refers to the anticipation, response, and recovery from error conditionsWriting 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.<ref name="dnatterrors"/>


[[Image:Producer-consumer.PNG|center|thumb|600px|'''Figure 8''':  producer-consumer diagram with error handling in the top loop]]
{| class="wikitable" style="text-align: left;"
|- style="vertical-align:top;"
! Aspect !! Details
|- style="vertical-align:top;"
| '''Error Generation''' is the creation of an [[Error cluster|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).<br><br>


The “event loop” (bottom) produces enumerated commands that are processed by the “cmd loop” (top). The outer case structure in the top loop traps for errors that are placed on the lower shift register.  The corresponding error case (not shown) allows error handling by “code” with different methods of notification. For example, a user interface application based on this design pattern might employ the '''General Error Handler.vi''' shown in '''Figure 3''' to display a dialog for particular errorsHowever, this method would not work for applications that run continuously without user interaction.
|| 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:
# (Preferred) Create an error value using one of the library tools, i.e. [[Error Ring]] or ''Error Cluster from Error Code.vi''
# Directly bundling '''status''' boolean, '''code''' numeric, and '''source''' string together.  Doing this will not automatically include the call chain and is very hard to find in code, as you will be searching all Bundle nodes. It is not recommended unless it is done in [[Real Time]], [[FPGA]], or if you are returning an error cluster directly from a non-G DLL.
|- style="vertical-align:top;"
| '''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.<br><br>


{| class="wikitable" border="1"
|| Propagation is accomplished using the error cluster and wiring from error inputs through the various code paths and out an error outputWhen 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.
|-
| For continuously running applications, an error dialog (or any other kind of dialog for that matter) would disrupt execution, causing data loss or some other event you are being paid to avoidLogging error information to file is a useful notification method for such applications.  This approach requires an error description, which is provided by the '''Error Code Database.vi''' (see '''Figure 9''') for specified error codes in LabVIEW.


[[Image:Error_code_database_connector.jpg|frame|center|'''Figure 9''':  connector for the '''Error Code Database.vi''']]
'''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|debugging]] difficult.


This locked VI, located in the library <labview\vi.lib\Utility\error.llb>, is easily found as a subVI of the '''General Error Handler.vi'''.  You could extend this database to handle user defined error codes and provide some type of error log.  For example, some Windows applications log errors to the '''Event Viewer''' (right-click on '''My Computer''' and select '''Manage''' from the popup menu) shown in '''Figure 10''' and '''Figure 11'''.  The '''eventcreate''' command can be used in Windows to log events to this application.  A VI [http://forums.lavag.org/downloads.html&showfile=86 log event error] for logging errors to the '''Event Viewer''' is available.
An error chain can be broken in three ways:


|This entire section of WIKI about "Error Handling" could benefit from a deep reading of the online help for the General Error Handler.vi. That VI has more facilities than folks typically know. FOR EXAMPLE:
# Neglecting to wire an output that is part of the error chain
# Zero-iteration [[For Loop|For Loops]]
# Sloppy Merge Errors ordering


The General Error Handler.vi includes an input parameter for the type of dialog, one option is "no dialog." I would STRONGLY recommended 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.
To attempt to avoid breaking the error chain, the following [[VI Analyzer]] test can be run:


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 Cluster Wired''' - Detects subVIs and functions with unwired error outputs
* '''Unused Code''' - Detects unwired output tunnels of structures
* '''For Loop Error Handling''' - Detects loop-related error propagation and Merge Errors ordering issues on loop error output tunnels (VI Analyzer Toolkit 2018 or later)
|- style="vertical-align:top;"
| '''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:
* Ignoring certain errors
* Retrying the operation
* Translating or Modifying an error
* Failing the operation and closing the program
<br><br>
||
[[File:Screen Shot 2019-06-27 at 1.50.14 AM.png|600px|thumb]]
See Stephen Loftus-Mercer's poster on [https://forums.ni.com/ni/attachments/ni/3044/3784/2/LabVIEW%20Error%20Responses.pdf 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.<ref name="dnatterrors"/>
|- style="vertical-align:top;"
| '''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.<br><br>
|| 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.
|- style="vertical-align:top;"
| '''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 [http://thecodelesscode.com/case/48 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."''
|}
|}


[[Image:Event_viewer.JPG|frame|center|'''Figure 10''':  '''Event Viewer''' in Windows]]
[[Image:Event_properties.jpg|frame|center|'''Figure 11''':'''Event Properties''' in Windows]]
<!-- Bill VanArsdale, 21:17, 3 May 2007 (CDT) -->


[[category:LabVIEW fundamentals]]
== External Links  ==
*[http://www.ni.com/getting-started/labview-basics/handling-errors Error Handling Basics by NI].
*[http://controlsoftwaresolutions.com/error-handling-strategies-labview/ David Maidman’s Blog Post].
*[https://forums.ni.com/t5/LabVIEW-Development-Best/quot-SOLID-Error-Handling-quot-presentation-at-NIWeek-2017/td-p/3629639 SOLID Error Handling by Dmitry].
*[http://www.ni.com/example/31253/en/ Structured Error Handler Express VI by NI]
*[http://thecodelesscode.com/case/48 The Codeless Code, Koan 48]
 
 
== References ==
<references>
<ref name="dnatterrors">Nattinger, Darren. [http://bit.ly/dnatterrors "What to Expect When You're Expecting an Error"] (NIWeek 2018)</ref>
</references>
 
[[Category:LabVIEW fundamentals]]
[[Category:Error Handling]]

Latest revision as of 14:53, 17 January 2021

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.[1]

Aspect Details
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:
  1. (Preferred) Create an error value using one of the library tools, i.e. Error Ring or Error Cluster from Error Code.vi
  2. Directly bundling status boolean, code numeric, and source string together. Doing this will not automatically include the call chain and is very hard to find in code, as you will be searching all Bundle nodes. It is not recommended unless it is done in Real Time, FPGA, or if you are returning an error cluster directly from a non-G DLL.
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:

  1. Neglecting to wire an output that is part of the error chain
  2. Zero-iteration For Loops
  3. Sloppy Merge Errors ordering

To attempt to avoid breaking the error chain, the following VI Analyzer test can be run:

  • Error Cluster Wired - Detects subVIs and functions with unwired error outputs
  • Unused Code - Detects unwired output tunnels of structures
  • For Loop Error Handling - Detects loop-related error propagation and Merge Errors ordering issues on loop error output tunnels (VI Analyzer Toolkit 2018 or later)
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:
  • Ignoring certain errors
  • Retrying the operation
  • Translating or Modifying an error
  • Failing the operation and closing the program



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.[1]

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."


External Links


References

  1. 1.0 1.1 Nattinger, Darren. "What to Expect When You're Expecting an Error" (NIWeek 2018)