Jump to content

How should "Error In" affect code execution?


Go to solution Solved by mje,

Recommended Posts

Hello,

 

For the past 2+ years, I've always thought that official LabVIEW nodes/VIs do nothing (and only output default values) if they receive an error in their "Error In" terminal. As a result, I wrote code like this:

post-30568-0-68721000-1431178893_thumb.p

(I thought that a memory leak could occur if an error input stopped Release Queue from doing its usual job)

 

Today, I discovered that nodes like Destroy User Event and Release Queue actually still work even if they receive an error. I guess this behaviour makes sense. However, I'm now wondering if there's a definitive guide on how errors should affect code execution -- Should I expect all nodes/VIs to do nothing if they receive an error, except for "cleanup" nodes/VIs?

 

The reason I investigated this is because I'm writing a library that uses an initialize-work-deinitialize pattern. To be consistent with official LabVIEW nodes/VIs, it looks like my "Initialize" and "Work" VIs should do nothing if they receive an error, but my "Deinitialize" VI should still attempt to free resources even if it receives an error. Would you agree?

  • Like 1
Link to post
  • Solution

The definitive guide would be the documentation. Every VI that takes an error in either has the "This VI provides standard error I/O functionality" statement or specifies what happens when an error is supplied. I always document my VIs in a similar manner, usually something like "this VI operates regardless of supplied error state" if not standard, or more specific when need be.

I agree with you and NI's practice of having release and destroy VIs always operate.

Over the last few years I've also started backing off from always having error I/O. Simple VIs which are incapable of generating errors don't have error cluster I/O. I'm looking at you accessor VIs (for the most part).

Link to post

 I'm looking at you accessor VIs (for the most part).

 

I changed my thinking on this a while ago too

Reads can be as simple as one in and one out: LVOOP Object input, accessor-data-item output

  • Like 1
Link to post

Today, I discovered that nodes like Destroy User Event and Release Queue actually still work even if they receive an error. I guess this behaviour makes sense. However, I'm now wondering if there's a definitive guide on how errors should affect code execution -- Should I expect all nodes/VIs to do nothing if they receive an error, except for "cleanup" nodes/VIs?

In general, that is correct.  But always check the documentation to be sure.  This last year we got bit by the Destroy Stream Endpoint (for Network Streams) not executing on an error.

Link to post

And I'm still waiting for the red "error in" terminals on VIs that operate regardless of error in

Maybe next year ...

That sounds like a good idea exchange.  The times I could think of using this for sure is on the defer front panel property node.  There have been times when I would defer the front panel, do some operation, then undefer.  If an error was generated during the "do some operation" part then an error goes into the undefer property node, and nothing happens.  I've since wrote my own wrapper around this function that adds some other features and still undefers on error, then merges them together for this reason.

 

In general, that is correct.  But always check the documentation to be sure.  This last year we got bit by the Destroy Stream Endpoint (for Network Streams) not executing on an error.

Ouch, good to know but NI (and all developers) should really try to perform closing operations even if an error is passed in.  I've never seen it as a written rule but it seems like a good best practice. 

Link to post

Thanks everyone, for the insightful discussion. I agree that it's most sensible to perform cleanups even if an error occurred, and the Network Stream example sounds like a design flaw.

 

Aside from cleanups though, I can't think of any other good cases which should run regardless of error -- do you guys do this in non-cleanup code?

 

As for accessors, I agree that read VIs for a simple number shouldn't have error I/O terminals. I still put them in write VIs though -- I avoid modifying my object's state if an error occurred beforehand. Does anyone feel strongly against this?

Link to post

Aside from cleanups though, I can't think of any other good cases which should run regardless of error -- do you guys do this in non-cleanup code?

 

I do. Particularly for string manipulation (regex, scan from string etc) where an error is too disruptive. One of my pet peeves, though, is the read from file VIs They give an error 4 when you request more bytes than are left in the file.This has prompted a few of us to create a "filter" vi to reset error 4 which should be a warning at most, IMO.

Edited by ShaunR
  • Like 1
Link to post

 One of my pet peeves, though, is the read from file VIs They give an error 4 when you request more bytes than are left in the file.This has prompted a few of us to create a "filter" vi to reset error 4 which should be a warning at most, IMO.

 

Out of curiosity, why are you even trying to read more bytes than are in the file?

Link to post

In general, that is correct.  But always check the documentation to be sure.  This last year we got bit by the Destroy Stream Endpoint (for Network Streams) not executing on an error.

I know this was an issue with LabVIEW 2010, but got the impression that it was fixed in later versions?

Link to post

This has prompted a few of us to create a "filter" vi to reset error 4 which should be a warning at most

Is there a reason you don't use the Filter Error made by OpenG which accepts a scalar or array of errors to filter?  This was made native in 2014, but only accepts a scalar for some reason.

Link to post

Thanks everyone, for the insightful discussion. I agree that it's most sensible to perform cleanups even if an error occurred, and the Network Stream example sounds like a design flaw.

 

Aside from cleanups though, I can't think of any other good cases which should run regardless of error -- do you guys do this in non-cleanup code?

 

As for accessors, I agree that read VIs for a simple number shouldn't have error I/O terminals. I still put them in write VIs though -- I avoid modifying my object's state if an error occurred beforehand. Does anyone feel strongly against this?

 

Any sort of inter-module communication will have certain messages that you want to get across regardless of the error.

Link to post

Any sort of inter-module communication will have certain messages that you want to get across regardless of the error.

 

I have a “Reply†method that always sends a message, since someone else is presumably waiting for it.  The reply is an error message if there is an error in, rather than the usual reply message.

  • Like 2
Link to post

I have a “Reply†method that always sends a message, 

Oh good point.  When I did this in the past I would actually send the error back with the reply.  So if a request was made to an analog actor to read some data, it would attempt to read the data then send it back, along with the data it would send back the error generated from the attempt to read.  Then the request gets the data and an error, and the error would then be handled where the request was made.

Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.