Jump to content

Aspects of error handling: Difference between revisions

From LabVIEW Wiki
Moved default and custom error codes to separate pages
Line 1: Line 1:
{{Template:ActiveDiscuss}}
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 clusters in your code assists in troubleshooting, modularity, and user friendliness.
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 clusters in your code assists in troubleshooting, modularity, and user friendliness.


Line 29: Line 28:
# G code that creates an error value (i.e. an [[Error Ring]], or using ''Error Cluster from Error Code.vi'')
# G code that creates an error value (i.e. an [[Error Ring]], or using ''Error Cluster from Error Code.vi'')


=== Default Error Codes ===
Output from a built-in node will result in a [[Default Error Code]]Output from an [[Error Ring]] or the ''Error Cluster from Error Code.vi'' can result in a Default Error Code or a [[Custom Error Code]].
The LabVIEW execution system contains a large list of standard and specific errors, encouraging the reuse of generic codes across applications. A list of generic errors codes can be found under the LabVIEW Help menu (figure coming soon...)Another method of parsing a small number of errors is to select the Help Explain Error menu item. This will launch an interface that allows the user to enter an error code, and a brief explanation is displayed (figure coming soon...). This interface is also accessible by right-clicking on a front panel error cluster, and selecting Explain Error.


=== Custom Error Codes ===
== Error Propagation ==
National Instruments has set several error codes aside for custom use. If an existing error code does not adequately describe the error condition, the user can define custom codes that are specific to the applicationCodes between 5000 through to 9999 are available for use, and do not need to conform to any other application. Although General Error Handler.vi can be used to define custom error codes, one can also create an XML file in the labview\user.lib\errors directory that contains custom error codes and their descriptions. This method is particularly useful if the user requires custom error codes to apply to several applications, or if the codes are used by several software engineers in a team or are to be distributed with an application.
'''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).  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 inputs 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 example, the XML filename must be in the format '''*-errors.txt''' (where '''*''' is user definable), and the internal file structure must adhere to the following format:
'''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.


<blockquote><br />
An error chain can be broken in three ways:
<?XML Version="1.0"><br />
<nidocument><br />
<nicomment><br />
This is a custom error code definition file for my application.<br />
</nicomment><br />
<nierror code="5000"><br />
User Access Denied!<br />
Contact the Security Department to gain clearance to perform this function.<br />
</nierror><br />
<nierror code="5001"><br />
User Unknown.<br />
Contact the People Development Department.<br />
</nierror><br />
<nierror code="5100"><br />
Driver Unable to Contact Instrument Database.<br />
Contact the Software Engineering Department Helpdesk.<br />
</nierror><br />
<nierror code="5200"><br />
Plug-In Module in R&D mode – not to be used in Production Environment.<br />
Contact the New Product Development Group.<br />
</nierror><br />
</nidocument>
</blockquote>


As can be seen, a file comment can be created within the <nicomment> tag space. Each custom error is defined as an <nierror> with it’s associated error code, and its error message is then placed inside the <nierror> tag space. Although hand coding a custom error code XML file is possible, the Error Code File Editor (Tools->Advanced->Edit Error Codes) provides a simple GUI for file creation and editing (figure coming soon...). Once custom error code files have been created and/or altered, LabVIEW must be
# Neglecting to wire an output that is part of the error chain
restarted for the changes to take effect.  It is often useful to define code bands during the project planning stage, setting aside bands for specific related error groups.
# Zero-iteration [[For Loop|For Loops]]
# Sloppy Merge Errors ordering


== Error Propagation ==
To attempt to avoid breaking the error chain, the following [[VI Analyzer]] test can be run:
'''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).  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 inputs 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|debugging]] difficult.
* '''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)


Here is a list of ways an error chain can be broken:
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.
 
* Neglecting to wire an output that is part of the error chain
* Zero-iteration [[For Loop|For Loops]]
* Sloppy Merge Errors ordering


== Error Response ==
== Error Response ==
'''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:
'''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.  The ways errors could be responded to include:
* Ignore certain errors
* Ignoring certain errors
* Retry an operation
* Retrying the operation
* Translate/Modify an error
* Translating or Modifying an error
* …and many more
* Failing the operation and closing the program
See Darren Nattinger's poster on [https://forums.ni.com/ni/attachments/ni/3044/3784/2/LabVIEW%20Error%20Responses.pdf Error Responses].
See Darren Nattinger's poster on [https://forums.ni.com/ni/attachments/ni/3044/3784/2/LabVIEW%20Error%20Responses.pdf Error Responses].


Although one of the simple error responses might be to unbundle the Status Boolean of the error cluster, and feed it to the conditional terminal of a case structure (figure coming soon...), the complete cluster can be wired to it instead (figure coming soon...).  The functionality of the code in (figure coming soon...) and (figure coming soon...) is identical, although its readability is vastly improved as the second example colors the case structure green for the No Error case, and red for the Error case. Wrapping the entire code of a SubVI within a conditional case structure based on the error input allows VIs at higher levels to continue functioning, without executing code that could be useless or even dangerous when an error has occurred.
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.  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.


== Error Display ==
== Error Display ==
Line 95: Line 68:
== Error Logging ==
== Error Logging ==
'''Error Logging''' involves taking errors generated by LabVIEW code and logging them to file for later analysis.
'''Error Logging''' involves taking errors generated by LabVIEW code and logging them to file for later analysis.
== Example ==
Consider the simple report generation example shown in (figure coming soon...).
A report is initially created, a file is then attached, the report is printed, and finally destroyed. The dataflow link between these SubVIs is the report’s reference number (refnum), which ensures each execute in a predefined order. If each of the SubVIs execute without error, then the process completes successfully.  Conversely, if one of the SubVIs encounters an error, subsequent SubVIs are unaware of the problem and attempt to execute regardless. In the example above, an error in the Attach a File to the Report SubVI will not cause the Print the Report SubVI to fail, resulting in a blank report print. If effective error handling is introduced (figure coming soon...), the Print the Report SubVI will know if an error has occurred before its execution is requested. If the functional code inside the Print the Report SubVI is enclosed within a conditional case structure based on the error input, the printing code is bypassed, and the error cluster is passed on to the next SubVI.
To attain a higher level of user interaction, standard SubVIs exist to alert the user to an error on the error cluster, and prompt for conditional actions. The Simple Error Handler.vi (figure coming soon...) allows for a basic level of error cluster status reporting, displaying detected errors in a dialog box, and prompting the user for an action based on the type of dialog input (for example, OK, Cancel, Stop, etc.).
The Simple Error Handler.vi is a wrapper for the lower level General Error Handler.vi. The latter (figure coming soon...) is more configurable, and permits the dynamic definition of custom error codes, and error exception handling. LabVIEW 7.0 brings with it an addition to the error handling function palette, Clear Errors.vi (figure coming soon...). This VI is simply an error in control and an
error out indicator, which are not linked on the wiring diagram, causing any errors on the wired error link to be cancelled. This VI can be useful when constructing custom error-handling VIs, including dialog boxes allowing user interaction that is not covered by the simple and general error-handling VIs, but should not be used alone. Although dumping the errors from the error cluster may be tempting, one must incorporate appropriate code to handle them.


== External Links  ==
== External Links  ==

Revision as of 02:14, 30 November 2018

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 clusters in your code assists in troubleshooting, modularity, and user friendliness.

The Error Cluster

The error cluster is a predefined LabVIEW cluster that is used to contain error status information. The cluster contains the following three components:

Name Data Type Description
Status Boolean Indicates if an error has occurred (TRUE = error, FALSE = no error).
Code 32-Bit signed integer A standardized error code specific to the particular error. LabVIEW has a table of default error codes, although the user is able to define custom error codes. See below for more information.
Source String Textual information often describing the error and the VI it occurred within.

Error Generation

Error Generation is the creation of an error value at the point that something goes wrong in your LabVIEW code. Error can only be generated in two ways:

  1. Output from a Built-in Node
  2. G code that creates an error value (i.e. an Error Ring, or using Error Cluster from Error Code.vi)

Output from a built-in node will result in a Default Error Code. Output from an Error Ring or the Error Cluster from Error Code.vi can result in a Default Error Code or a Custom Error Code.

Error Propagation

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). 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 inputs 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)

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.

Error Response

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. The ways errors could be responded to include:

  • Ignoring certain errors
  • Retrying the operation
  • Translating or Modifying an error
  • Failing the operation and closing the program

See Darren Nattinger'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. 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.

Error Display

Error Display is the act of displaying error information to the end user and/or code developer. 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

Error Logging involves taking errors generated by LabVIEW code and logging them to file for later analysis.

External Links