Jump to content

Error Handling Thoughts


Recommended Posts

Just to clarify, I don't mean to imply that I think wrapping an entire sub VI block diagram in an error cluster is pointless. In fact, there specifically *is* a point in doing it--to ensure the sub vi code doesn't execute if there's an error. Turns out that's not a goal that contributes to my code quality or clarity when applied universally to my projects. *shrug*

Or to ensure that the sub vi code DOES execute if there is an error :D In fact I just wrote a vi today that does nothing in the no error case but in the error case it generates a user event.

I didn't mean to imply that I think it is always pointless. I said "mostly" although a better word would have been "usually". There are many situations where it is definitely a good thing and even necessary. I know we are on the same page but what I meant to say is that error cases are usually a waste of a some perfectly good pixels.

Take for example a vi that opens a file, reads it and appends a string, writes the results then closes the file. It would be pointless in this vi to wrap those functions in an error case. If you call the vi with an error in then those primitives already skip what they do in an internal error check. But I suppose that there is a difference in that the open, read, write and close each have to check for an error where they could have been skipped. But how expensive can that be compared to the normal condition in which there is file IO! In that vi I can see no reason whatsoever to use (or not use) an error case. I just don't see the difference.

This is the way I have been programming for as long as I have been programming. When it comes to an error case I just use one if I need to or if it seems to make sense. But I almost always have error terminals on any vi that I write. When they are not used they are just wired together internally.

For my CLD exam I will put error case structures in any sub vi.

Man you sure can start some threads. First it was the QSM and now this. In both of these you make some very good arguments against what everyone seems to just accept. What next?

Link to comment

What I take away from this thread is that we have a lot of really good architects and developers that participate on LAVA and understand the importance of having some sort of error handling strategy. It hardly matters how you do it as long as you do it and do it consistently. I use the error structure (mostly because the method templates on classes add them) but the important thing is that it makes me think about how I need to handle errors that might be generated. Should I catch and discard? Should I just make the VI a no-op and pass on the error cluster? Do I use a dialog (seldom do I find this to be a good idea but every once in while it's the right answer)? As long as developers are thinking about error handling then their code will be better.

Mark

Link to comment

I don't see how thus point is a benefit of not wrapping

It isn't. I interpreted Black Pearl's suggestion to "Always wire the error wire to the SubVIs" as connecting to the error in terminals of all the sub vi's on a given block diagram, not connecting the error terminals *inside* the sub vi's block diagram. Could be I completely misunderstood...

I meant to say is that error cases are usually a waste of a some perfectly good pixels.

"Save the Pixels." We should get bumper stickers made...

But I almost always have error terminals on any vi that I write. When they are not used they are just wired together internally.

Same with me. Even my accessors have error terminals even though they don't contain an error case.

Man you sure can start some threads. First it was the QSM and now this. In both of these you make some very good arguments against what everyone seems to just accept. What next?

Left to Right data flow? I'm thinking of writing an article describing my spiral data flow model... ;)

As long as developers are thinking about error handling then their code will be better.

Absolutely agree. Expecting to tack on error handling when the functional code is already in place is asking for trouble.

Link to comment

Ok, I decided to do my own benchmarking as I am interested in overhead.

I wanted to get a feel for the overhead.

SubVI has error-in, error-out wired straight through whilst Error is cased out and wired through.

post-10325-0-33428800-1299141155_thumb.p

Here is the results, took a small subset to post but data is pretty consistent IMO (can log more if I can be bothered).

What is interesting is LabVIEW 2010 is the opposite to all the others?

Anyways, seems pretty insignificant over 1M iterations.

Note: Data is in (ms).

post-10325-0-96236500-1299141152_thumb.p

Attached is the code if anyone else wants to see it.

LV82.zip

Code is in LabVIEW 8.2.1

Link to comment

Code is in LabVIEW 8.2.1

I modified SubVI With Errors.vi by adding some file IO (open, read, write, close) and removed the case structure. I set the error in constant to true and in LabVIEW 2010 the numbers I got were:

  • SubVI 760mS
  • Error 1101mS

As expected there is a performance hit since four prims are checking for an error. But it is rare that I consider performance when making a decision like this. Something is wrong and the vi will be called only once with an error before the application is shutdown or the error is responded to and cleared or corrected downstream.

I know that NI recommends the case structure but I find it cleaner without it. When I write a vi I tend to let its functions or sub vis do their own error checking. If I am using code in a vi and do not know how that code will respond to errors then I will put it in an error check case structure. If I know that the code in the subvis I am using wrap all their code in an error checking case structure then I don't worry about it. But the decision is not about performance it is about Saving The Pixels.

That's a lot of LabVIEW versions you have! I only have one :angry:

Link to comment
  • 2 weeks later...

Back in February, Daklu asked me to review this thread, but I missed seeing his private message. Sorry about that...

For good error handling, the "error case structure" (hereafter called ECS) only needs to be on the leaf subVIs. In other words, if your subVI is composed entirely of other subVIs or built-in nodes that already check for error, there's no reason for your subVI to check for error. Adding the ECS just adds an unneeded check. It improves performance in the error case, which is the less common case. Is the hit minor? Yes -- just a single "test and jump" assembly instruction. Can that hit be devastating? When replicated thousands of times, yes.

On the next topic, how many of you would consider this to be good code?

post-5877-0-05786600-1300415698_thumb.pn

Having error terminals on data accessors is equivalent to this. It's a complete waste. This may make you ask, "So, if that's your opinion, and you wrote the templates for data accessors for LV classes, why do the templates have error terminals?" Well, my opinion isn't the only one that matters. :-) And I am the one who later added the options to the dialog to create accessors without error terminals.

At the moment, there's no performance hit other than the case structure check to having the error terminals. However, LV's compiler continues to improve, and in a not too distant future (maybe next year), the version without the case structure should see a significant performance boost over the version with the case structure. The compiler can do more to optimize code that will always execute than to optimize code that conditionally executes.

Link to comment

I'm thinking of writing an article describing my spiral data flow model... ;)

Reference material? :D

index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=454

What is interesting is LabVIEW 2010 is the opposite to all the others?

Pure guess - changes in the compiler.

In other words, if your subVI is composed entirely of other subVIs or built-in nodes that already check for error, there's no reason for your subVI to check for error.

This assumes that a) you know how the subVIs/prims handle errors and b) you don't want to do anything with the "local" error yourself (such as appending data to the source element). Not necessarily a problem (although B is if you want to be sure you don't lose error data), but it's easier to add the ECS in when you start and then you don't have to worry about this.

Luckily, my code never has errors, so I don't run into these issues. ;)

Link to comment

With my limited understanding of the compiler, here the exlanaition.

When you wire both terminals (inside the subVI), the data is unchanged. If I don't wire the terminals in the SubVI, it actually changes whenever an error comes in.

If I don't wire the SubVI in my benchmark VI, a new buffer must be allocated each iteration.

Anyhow, I'm also more interested in the functionality aspects on error handling in this discussion.

Felix

I think Greg McKaskles explanation from the "Clear as Mud" thread on the dark-side explains the hit about not wiring the input under the section where he talks about the default value having to be supplied when not wired.

I generally look at the code for obvious errors that could occur either by mis-use by others (or myself) or what would be the follow-up effect, of the code not working and how difficult it would be to diagnose an error based on the error cluster info. For code that touches a lot of stuff for the first time, I will use nest error cluster so that I can clearly diagnose a file I/O error from the DAQ error that could result from a bad config (a file error) or the hardware is shut-off.

In the early days of UNIX there was no error recovery or logging built into the OS. The philosophy was "well fix the hardware then start the OS." That left a bad mark on me so know I "drop bread crumbs" in my code so that I can nail issue if the they come up.

But not all of my code is wrapped in error clusters. Number crunching, bit banging etc...

I appreciate the report about the performance being about the same between through wire vs not.

even if there was a performance hit that could be meassured, I'd still use error clusters for all but the most demanding performance situations. Anybody can drive a car 100 MPH, but to do it safely is another story.

I once posted here about the "extra inputs" on the icon connector actually incurring a performance hit that could be measured under the right conditions. Even after learning that fact, I still include extra connectors on the icon, to mkae my life easier, even if ther may never be a need.

Take care,

Ben

Link to comment

@Yair, I actually thought about that thread when I was writing my post. :)

I think Greg McKaskles explanation from the "Clear as Mud" thread on the dark-side explains the hit about not wiring the input under the section where he talks about the default value having to be supplied when not wired.

I looked up the thread but didn't see any references to not wiring the input terminal. That thread focuses on where the terminal should be placed on the block diagram. Any other ideas where it might be?

In the early days of UNIX there was no error recovery or logging built into the OS. The philosophy was "well fix the hardware then start the OS." That left a bad mark on me so know I "drop bread crumbs" in my code so that I can nail issue if the they come up.

I like to sprinkle my code with debug messages to provide an ordered list of events that occured during execution. It takes a little more time to set up but it's saved me loads of time figuring out what went wrong, especially when if I've got many parallel threads interacting with each other.

Link to comment

@Yair, I actually thought about that thread when I was writing my post. :)

I looked up the thread but didn't see any references to not wiring the input terminal. That thread focuses on where the terminal should be placed on the block diagram. Any other ideas where it might be?

I like to sprinkle my code with debug messages to provide an ordered list of events that occured during execution. It takes a little more time to set up but it's saved me loads of time figuring out what went wrong, especially when if I've got many parallel threads interacting with each other.

I can't find that reference either so please forget what I said until I can prove it.

Re:messages

I have re-use that lets me quickly compose messages that clearly detail how my code was bieing mi-sued and what they need to do to fix it and why they should not be knocking on my cubilce and complaining. The only time that has failed me is when a developer failed to include my code in the build. :frusty:

Ben

Ben

Link to comment

I have re-use that lets me quickly compose messages that clearly detail how my code was bieing mi-sued and what they need to do to fix it and why they should not be knocking on my cubilce and complaining.

Sounds useful. Sharable?

I've had error messages that say things like, "If you're seeing this error, the developer who wrote the code didn't read the documentation. Find him and smack him." But they tend to be few and far between.

Link to comment

I've had error messages that say things like, "If you're seeing this error, the developer who wrote the code didn't read the documentation. Find him and smack him." But they tend to be few and far between.

A former coworker put an error message in that said (paraphrased) 'this condition can never happen so you'll never see this message'. Unfortunately it did happen and we received a call from an irate customer. I've been rather cautious about what I put in my error messages since, especially since I wouldn't put it past some of my customers to smack me.

Tim

Link to comment

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.