Error handling strategies in LabVIEW

David Maidman –  Control Software Solutions

Introduction

Error handling is an essential part of a professional LabVIEW application, however is something that is often overlooked. Without adequate error handling applications can be hard to debug, provide a bad user experience and in the worst case can cause damage to equipment, loss of data and even injury.

When starting out with LabVIEW one of the first things we are taught is the importance of error handling. In these early days the general advice is that we should always enclose block diagram code in an error case and that we should always wire errors between our subVIs. However, in practice this advice does not always provide an adequate error handling strategy when creating professional applications, and in some circumstances causes more problems than it solves.

Local Error Handling

Often when an error occurs, rather than passing it downstream it can be dealt with there and then. How you handle the error depends on the specific error and the software requirements. Often when an error occurs we might decide to handle it locally by one of three ways; ignore it, modify it, or retry.

Ignore

Sometimes it is possible to simply ignore an upstream error. One common example might be a communications timeout error when reading from a TCP connection. In the case of a timeout the read VI returns an error because it failed to successfully carry out its primary job, however in the context of your application this might not be seen as an error and therefore it can be cleared (for example it could be that there are no messages to read).

Figure 1 clearing a timeout error

Figure 2 example of how a specific error can be cleared

Modify

Some errors may provide information that can be used downstream, even if you do not consider them to be errors. In this case you could choose to downgrade an error to a warning. In this case the error cluster retains the useful information, however does not prevent downstream code from executing. One example would be when creating a new directory: if the directory already exists an error will be generated, however if the reason you are creating the directory is simply to ensure that it exists then you might not want an error to be generated.

Figure 3 downgrading an error to a warning

Another reason you might want to modify an error is to change the error code to one specific to your application.

Figure 4 changing a default error code to one specific for the application

Retry

Sometimes you might only be interested in an error if it occurs a number of times. An example might be when attempting to initialise a DAQ device when the device has not been connected. In this example you might clear the error and then retry.

Figure 5 implementing a ‘retry on error’ strategy

Asynchronous Error Handling

You might not always want to handle errors locally and therefore it might be necessary to pass error information to another module to be handled. In this case you can use queued message handlers if you have a dedicated error handling module, or by user events if you want modules (for example a state controller or user interface) to subscribe to error messages.

Figure 6 adding errors to a queue to handle in another loop

 

Figure 7 publishing errors as events to be handled by subscribing processes

In practice you are likely to use a combination of local and central error handling depending on the requirements of your project.

Error Handling Guidelines

  1. Before enclosing the block diagram of a VI in an error case consider as yourself the question ‘should the code in this VI run if there is an upstream error?’ Only if the answer is ‘No’ should you enclose the code in an error case.
  2. In general shutdown code should always execute, therefore do not enclose the code within an error case, rather merge the input error with the error stream at the output of the subVI.
  3. Remember to maintain separate error streams for unrelated functions.
  4. If possible handle errors where they occur.
  5. Consider what you what you want to happen in the event of an error (ignore, retry, modify).
  6. Errors can provide useful information – downgrade to warnings if you want to maintain the error information without triggering an error.
  7. Handle errors gracefully and always avoid crashing the application when an error occurs.
  8. Log unhandled errors to allow useful debug information.
  9. Always consider error handling in the requirements and detailed design phase of your project.

Figure 8 do not enclose shutdown code in an error case

 

Figure 9 merging incoming errors with the output error stream to ensure the shutdown code executes

Further Information

For more information on any of the topics you have read in this article, or for more information on LabVIEW programming contact us:

Leave a Reply

Your email address will not be published. Required fields are marked *