You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, errors are signalized with ERR pulses. They require much boilerplate to pass an error further (big any’s with all ERR united) and do not carry any information about the error reason. Also, using pulses for errors makes it hard to express that a value is malformed. We can improve the system by introducing a dedicated concept for errors.
Errors concept
From time to time things go wrong. A sensor can refuse to respond, a server can become unavailable, a list index can fall out of range. Nodes should have a way to signalize that they fail so that other nodes which use their results can recover or show the error to a device user. XOD makes it possible with an error concept.
A node can raise an error to demonstrate that it has failed to evaluate. When the node raises an error all downstream nodes become “infected” and enter the error condition too. They won’t be evaluated as long as the original error is in effect. Their downstream nodes—in their turn—inherit the same error as well. The cascade goes on until the whole downstream subgraph of the original node is considered erroneous.
Errors are neither values nor pulses. They spread via links regardless of the link types and node evaluation policies. Errors are an overlay mechanism.
Any error risen has a code attached. The code loosely describes the error reason. It is a choice between one of the values defined by XOD. With the codes, someone who faces an error can better understand how to deal with it. Examples of the error codes are:
E16 (Bad Use) — the node input values are invalid
E32 (Hardware Fail) — general hardware communication problem
E48 (Network Fail) — network or internet communication failure
In contrast to errors, the error codes are values of a type Errcode which exist specifically to handle errors.
The error mechanism in XOD is something between exceptions in C++ or Python, and Either monads in Haskell or other functional programming languages. Unlike the “elder brothers” XOD does not carries custom error objects around: to keep resource usage at minimum, only short error codes are used.
During a transaction, if an erroneous node should be evaluated following the execution model rules, it will be evaluated if it raises an error but did not inherit any. This way it can recover and “cure” the whole downstream subgraph bringing back the normal operation.
Also, a node may declare itself as an error catcher. In this case, it will be evaluated even if it inherits an error. Such nodes are used to recover from far upstream errors and take a specific action when something went wrong. In particular, the standard library provides the following error handlers:
if-error
pulse-on-error
error-code
With these nodes, you can extract the code out to display it, retry an attempt, or freeze the device until a reboot.
At another end, to produce an error use the error node or the raiseError function in the C++ code.
Acceptance criteria
The new Errcode built-in type is introduced; accepts literals of the Exx form
C++ API has functions raiseError, getError<input_IN>(ctx)
C++ supports #pragma XOD catch enable
The if-error, pulse-on-error, error-code, and error nodes are implemented
How to implement
Add a uint8_t error field to the Node structs
Use the MSB to denote whether an error is own (0) or inherited (1)
In runTransaction, for each node, update the error value by picking and merging upstream errors
In runTransaction, expand the logic of dirtiness markup to mark downstream nodes dirty if the current node just got or lost the error state
If a node inherits an error and does not declares itself as a catcher, skip evaluate and go on
The text was updated successfully, but these errors were encountered:
Rationale
Currently, errors are signalized with
ERR
pulses. They require much boilerplate to pass an error further (bigany
’s with allERR
united) and do not carry any information about the error reason. Also, using pulses for errors makes it hard to express that a value is malformed. We can improve the system by introducing a dedicated concept for errors.Errors concept
From time to time things go wrong. A sensor can refuse to respond, a server can become unavailable, a list index can fall out of range. Nodes should have a way to signalize that they fail so that other nodes which use their results can recover or show the error to a device user. XOD makes it possible with an error concept.
A node can raise an error to demonstrate that it has failed to evaluate. When the node raises an error all downstream nodes become “infected” and enter the error condition too. They won’t be evaluated as long as the original error is in effect. Their downstream nodes—in their turn—inherit the same error as well. The cascade goes on until the whole downstream subgraph of the original node is considered erroneous.
Errors are neither values nor pulses. They spread via links regardless of the link types and node evaluation policies. Errors are an overlay mechanism.
Any error risen has a code attached. The code loosely describes the error reason. It is a choice between one of the values defined by XOD. With the codes, someone who faces an error can better understand how to deal with it. Examples of the error codes are:
E16
(Bad Use) — the node input values are invalidE32
(Hardware Fail) — general hardware communication problemE48
(Network Fail) — network or internet communication failureIn contrast to errors, the error codes are values of a type
Errcode
which exist specifically to handle errors.During a transaction, if an erroneous node should be evaluated following the execution model rules, it will be evaluated if it raises an error but did not inherit any. This way it can recover and “cure” the whole downstream subgraph bringing back the normal operation.
Also, a node may declare itself as an error catcher. In this case, it will be evaluated even if it inherits an error. Such nodes are used to recover from far upstream errors and take a specific action when something went wrong. In particular, the standard library provides the following error handlers:
if-error
pulse-on-error
error-code
With these nodes, you can extract the code out to display it, retry an attempt, or freeze the device until a reboot.
At another end, to produce an error use the
error
node or theraiseError
function in the C++ code.Acceptance criteria
Errcode
built-in type is introduced; accepts literals of theExx
formraiseError
,getError<input_IN>(ctx)
#pragma XOD catch enable
if-error
,pulse-on-error
,error-code
, anderror
nodes are implementedHow to implement
uint8_t
error field to theNode
structsrunTransaction
, for each node, update the error value by picking and merging upstream errorsrunTransaction
, expand the logic of dirtiness markup to mark downstream nodes dirty if the current node just got or lost the error stateevaluate
and go onThe text was updated successfully, but these errors were encountered: