Jump to content

Modern error cluster


Recommended Posts

I'm sitting in a cafe by the Baltic Sea drinking my cafe Latte and reading the forums with my laptop. This is a place where I come when I need to design my software and today is one of those days. The sun is shining and the sea is frozen. It's -20 C (-4 F) cold but still the combination of pure white snow and bright sun shine makes it an excellent weather. :D

To the topic. I think that error system that is based on error codes and source strings is not enough for modern applications and there needs to be a better system. However we don't want to loose backward compatibility. Therefore I propose the following. Let's use the source field of error cluster to pass both multiple errors and any "object" that is actually carrying the error related information. With object I denote to any LabVIEW type both classic by-value types and LVClass objects.

The idea is that when error occurs, user can throw an error object, that is any data, that would be flattened to string and appended to the source field of error cluster. The developer can then try to catch these errors by matching the type of the object to some sample types. LabVIEW would provide primitives for throwing and catching errors. Classic errors could be thrown and catch using the classic error cluster as an object type. If the object thrown would be a LVClass object, then a more general class could be used to catch a more specific class error i.e. the type match doesn't need to be exact but parent type would match a child type error.

I wrote a draft (below) of what I'd like source field of the error cluster to be like. The error cluster would be able to hold one or more error objects of arbitrary LabVIEW type. I use notation that is similar to BNF grammar, I assume that most of you are not familiar with BNF grammar so I try to explain the notation shortly below.

I also think it could be a good idea to combine the error objects I proposed with an easy mechanism to select one of the built-in error classes to throw and specify the content of the class. Furthermore it would be a good idea to allow user to browse trough built-in error classes when writing an error handler.

So here is my second proposal. Include a new tool "Error Specifications" to LabVIEW that looks and feels like LabVIEW options dialog. Instead of the category tree on the left there would be a LabVIEW error class hierarchy from which user could select one of the build-in error classes to throw. When an error is selected from the tree, the right hand side of the window would show error specification options for this particular error. There would be a new express node or XNode (or similar) "Throw Error Express" that would open this dialog when dropped to block diagram. The developer could interactively specify the error to throw. The node would have optional inputs for parameters that the developer cannot interactively specify but that needs to be specified by wiring the runtime data to the node. When this node is executed, it would add a new error object to the error cluster according to the interactive specifications. The performance of this new node is not that important as it would only be executed when an error has already occurred.

For catching errors a new stacked diagram would be needed or rather stacked sequence needs to be modified accordingly. The idea is that stacked sequence could have shift registers that allow passing data from a frame to the next frame so that user doesn't need to add sequence locals for each frame separately. The first frame could be used as a "try statement". The next frames can be used for handling errors. Error cluster could be wired to such a new kind of shift register of a stacked sequence. Each frame would be responsible for handling one particular type of errors. This makes the code clearer to read as the error catching cases are hidden and don't take 80% of the space in each block diagram. To increase the performance user could force the sequence to ignore the error frames if error has not occurred. Perhaps this could be a default behaviour if an error cluster is wired to a shift register of such a sequence. Color coding could indicate this default behavior in a similar way than when a error cluster is wired to a case structure.

Furthermore for catching the errors a new interactive express primitive would be needed. This primitive would catch an error user has interactively specified by selecting one of the build in classes from error class hierarchy. If error would be catch this node would return the catch object together with "error catch" boolean that can be used to control if further actions need to be made. This node would execute very fast if no errors have occurred.

In addition to these two new express nodes there needs to be more advanced built-in primitives for throwing and catching errors that the new express nodes would rely on. The error hierarchy browser of the new express nodes needs to be extensible so that developers can add new errors to the hierarchy and distribute these additions somehow together with their libraries. Perhaps a new directory error.lib could be used for user defined error classes that would be search by the interactive tool.

For the new error system to be helpful, existing built-in functions and libraries should be modified so that they would throw these modern errors. General error handler and user defined error handlers could still handle them but a modern error handler would do it better. Second a well designed hierarchy of error classes is needed for the model to be useful. When designing the hierarchy, some sort of dialog or probe method in the "general error class" is needed so that developers could create their own error dialogs easily.

Tomi

================= Modern Error Handling Specifications DRAFT ====================

x y denotes x followed by y

[x] denotes zero or one occurrences of x.

{x} denotes zero or more occurrences of x

x | y denotes one of either x or y

'a' denotes literal value a

String denotes any text string without '<' character

Binary flattened binary string of anything

Int denotes i64 integer in binary format

UInt denotes u64 integer in binary format

=== The specification for the source field of error cluster ===

SourceField ::= Classic | Modern

=== The specification of the classic error, that is the present format of error clusters ===

Classic ::= SourceString [Reason | Details]

SourceString ::= String

Reason ::= '<err>' String

Details ::= '<append>' String

=== The specification of modern errors that could coexsist with classic errors ===

Modern ::= FirstSource '<objects>' ObjectCount FirstErrorObject {ErrorObject}

FirstSource ::= SourceString

ObjectCount ::= UInt

=== Specification of error objects that could be thrown with the error cluster ===

=== and later catched by matching with different types ===

FirstErrorObject ::= ErrorObject

ErrorObject ::= ObjectLength BinarySourceString Anything

BinarySourceString ::= StringLength String

Anything ::= StringLength Binary

StringLength ::= UInt

Link to comment

I have nothing specific to add for the moment but I like the idea to get a more exception like mechanisme in LabVIEW error handling. That this would be possible with maintaining compatibility to the old cluster I hadn't even considered. At least NI has an internal way of mutating VIs automatically when upgrading them to a new version (the update specs are in binary format in Resources/vicnvrt somehow), but staying compatible would also allow to use such a mechanisme in older versions of LabVIEW.

Rolf Kalbermatter

Link to comment

One more addition. As the proposed modern error cluster could hold multiple errors simultaneously, the catch nodes need to be able to catch multiple errors if there are more than one errors of the same type. Perhaps the catch function could simply return array of objects of user specified type instead of a simply single object. Alternatively the same node needs to be revisited as many times as errors of the type are no longer found. This could be alternatively achieved if the modified stacked sequence could have a revisit frame input terminal at the inner side of the right end.

There may be other shortcoming as I haven't thought of this concept too deeply.

This discussion is somewhat related to an earlier discussion here at LAVA where I submitted an example how to thorw and catch errors using the error cluster.

Tomi

Link to comment
One more addition. As the proposed modern error cluster could hold multiple errors simultaneously, the catch nodes need to be able to catch multiple errors if there are more than one errors of the same type. Perhaps the catch function could simply return array of objects of user specified type instead of a simply single object.

Hmm, I'm not a fan of having yet another structure. That's extending the basics of the language and that should not be done without really deep thought. Before you know it the core of the LV language is obfuscated by all kind of extra's that could have been implemented using already existing mechanisms. An example of this is the waveform type. The waveform has been created as a new type of object, while functionally it could internally have been a cluster. The fancy waveform nodes could have been there, but NI could have used clusters internally. Using existing things (e.g. datatypes) can prevent a lot of trouble that you can get when introducing new things.

I've been working on collecting multiple errors in an XML way including extracting them again to an array of error clusters. That's no problem with the current system. I would appreciate it if NI would do more of these things for us.

I've written my own error catcher. It is attached here.

It perhaps good for analysis to realize that there are two kinds of errors:

1. errors from an underlaying system, like a library or system call;

2. errors that you create in the application itself (excluding self-written libraries).

An error system should be able to facilitate and transport both types of errors.

For the latter you usually don't need catching errors, functions that are called usually either work or fail, and distinction is usually not important for the program. Textual info is needed for the user. For the first you need some way to distinguise errors in order to be able to do different things when they occor. Right now that can perfectly be done with the error code.

I don't mean to say the error system should not be extended. But it should stay as transparent as it is now. Maybe the main problem with an error object is right now that LV object are not very transparent (cannot be shown on the FP for example). I think that should be improved first.

BTW error stuff should not be in the Time and Dialog palette, but in the Application Control pallete ! Because that's what it does, determining program flow.

Joris

Download File:post-1555-1171018865.vi

Link to comment
I don't mean to say the error system should not be extended. But it should stay as transparent as it is now. Maybe the main problem with an error object is right now that LV object are not very transparent (cannot be shown on the FP for example). I think that should be improved first.

The error implementation of the modern error cluster I proposed can be divided into two separate things. First the nodes thorw and catch any LabVIEW type using the error cluster. This can be implemented without modifying present code at all, simply add two new built-in nodes that would throw & catch any LabVIEW objects and extend the stacked sequence with a shift register. That would allow users to thow and catch errors in more complicated applications but would have simply no effect to those who didn't want to use this more advanced error system.

Tomi

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.