Exceptions during Operation calls

We're trying to determine the best way to deal with exceptions when an Operation is called.

As a test, we set up a simple operation that returns an incrementing int when called and set it to run in OwnThread. When called, it works just as expected, both using the .call() and .send()/.collect() methods. But, when I force the operation to throw a runtime_error, behavior is not what I would personally expect.

When call() is used, the receiving component catches a C++ exception and its thread is stopped. Deployer then hangs, blocking, waiting for the operation call to return. This is understandable.

When send() is used, the receiving component catches a C++ exception and its thread is stopped, as expected. But, when I call handle.collectIfDone(val), I get a SendNotReady return. I'd expect to get a SendFailed (due to the exception). And because of this, there's no good way to determine if the other end is just taking a while, or if it has thrown. Or is there?

How should an operation caller deal with an operation that may throw an exception?

FWIW: I found this thread http://www.orocos.org/forum/rtt/rtt-dev/operation-and-c-exception, but I didn't see a resolution.

--
Dustin Gooding
NASA/JSC Robotics

Exceptions during Operation calls

Hi Dustin,

On Tue, Jan 24, 2012 at 4:41 PM, Gooding, Dustin R. (JSC-ER411) <
dustin [dot] r [dot] gooding [..] ...> wrote:

> We're trying to determine the best way to deal with exceptions when an
> Operation is called.
>
> As a test, we set up a simple operation that returns an incrementing int
> when called and set it to run in OwnThread. When called, it works just as
> expected, both using the .call() and .send()/.collect() methods. But,
> when I force the operation to throw a runtime_error, behavior is not what I
> would personally expect.
>
> When call() is used, the receiving component catches a C++ exception and
> its thread is stopped. Deployer then hangs, blocking, waiting for the
> operation call to return. This is understandable.
>
> When send() is used, the receiving component catches a C++ exception and
> its thread is stopped, as expected. But, when I call
> handle.collectIfDone(val), I get a SendNotReady return. I'd expect to get
> a SendFailed (due to the exception). And because of this, there's no good
> way to determine if the other end is just taking a while, or if it has
> thrown. Or is there?
>
> How should an operation caller deal with an operation that may throw an
> exception?
>
> FWIW: I found this thread
> http://www.orocos.org/forum/rtt/rtt-dev/operation-and-c-exception, but I
> didn't see a resolution.
>

There is a patch which fixes this behavior:

http://bugs.orocos.org/show_bug.cgi?id=918

I've been slapped before because I'm not applying it. I need to find a way
to reserve some 'maintenance' time since I'm occupied with other (fun)
things and most of it just works for us as it is :-)

Peter

Exceptions during Operation calls

On Tue, 24 Jan 2012, Gooding, Dustin R. (JSC-ER411) wrote:

> We're trying to determine the best way to deal with exceptions when an
> Operation is called.
>
> As a test, we set up a simple operation that returns an incrementing int when
> called and set it to run in OwnThread.  When called, it works just as expected,
> both using the .call() and .send()/.collect() methods.   But, when I force the
> operation to throw a runtime_error, behavior is not what I would personally
> expect.
>
> When call() is used, the receiving component catches a C++ exception and its
> thread is stopped.  Deployer then hangs, blocking, waiting for the operation
> call to return.  This is understandable.
>
> When send() is used, the receiving component catches a C++ exception and its
> thread is stopped, as expected.  But, when I call handle.collectIfDone(val), I
> get a SendNotReady return.  I'd expect to get a SendFailed (due to the
> exception).  And because of this, there's no good way to determine if the other
> end is just taking a while, or if it has thrown.  Or is there?
>
> How should an operation caller deal with an operation that may throw an
> exception?

Forget about exceptions! Their behaviour is not portable over different
runtimes, let alone over distributed hardware. Exceptions are one of those
topics that designers of programming languages introduced in their
object oriented languages while forgetting about component based
applications. Both are _not_ the same, since the former is all about
compile time system building, and the latter about (possibly)
deployment-time and runtime system composition; there is no exception
semantics that is portable over existing programming languages and existing
frameworks. So, at best, you will make a system that has a lock-in into RTT
and C++. (And, to paraphrase Voltaire, even if you do not agree with me
that an Orocos lock-in is a bad thing, I will fight for your right to
think so :-))

The way out: events.

> FWIW: I found this
> thread http://www.orocos.org/forum/rtt/rtt-dev/operation-and-c-exception, but I
> didn't see a resolution.
>
> --
> Dustin Gooding
> NASA/JSC Robotics

Herman

Exceptions during Operation calls

On 01/24/2012 08:37 PM, Herman Bruyninckx wrote:
> Exceptions are one of those
> topics that designers of programming languages introduced in their
> object oriented languages while forgetting about component based
> applications. Both are _not_ the same, since the former is all about
> compile time system building, and the latter about (possibly)
> deployment-time and runtime system composition;

> there is no exception
> semantics that is portable over existing programming languages and existing
> frameworks.
Exceptions have the same semantic in all modern programming languages.

> So, at best, you will make a system that has a lock-in into RTT
> and C++. (And, to paraphrase Voltaire, even if you do not agree with me
> that an Orocos lock-in is a bad thing, I will fight for your right to
> think so :-))
Again, I don't see why. Exceptions are used heavily in a lot of
programming languages and even PASSED on the border of these languages.

I cannot disagree more. It is all but normal to allow operations to
throw exceptions since operations (as any RPC mechanism) *are* the bit
that component-based systems borrow to these programming languages.
Which is, indeed, one of the reasons why relying on operations should be
limited to very special cases.

For other type of interaction with components, I do agree. Since
component-based systems are *not* using the same paradigm than
programming languages, events (such as state changes) are a better
reporting mechanism.

Exceptions during Operation calls

On Wed, 25 Jan 2012, Sylvain Joyeux wrote:

> On 01/24/2012 08:37 PM, Herman Bruyninckx wrote:
>> Exceptions are one of those
>> topics that designers of programming languages introduced in their
>> object oriented languages while forgetting about component based
>> applications. Both are _not_ the same, since the former is all about
>> compile time system building, and the latter about (possibly)
>> deployment-time and runtime system composition;
>
>> there is no exception
>> semantics that is portable over existing programming languages and existing
>> frameworks.
> Exceptions have the same semantic in all modern programming languages.

But you can't "serve" a Java exception in a C++ component... In other
words, the _handling_ of exceptions as they are provided as programming
language primitives is _not_ portable. So, it is not recommended to rely on
them in a component based design. Simple.

>> So, at best, you will make a system that has a lock-in into RTT
>> and C++. (And, to paraphrase Voltaire, even if you do not agree with me
>> that an Orocos lock-in is a bad thing, I will fight for your right to
>> think so :-))
> Again, I don't see why. Exceptions are used heavily in a lot of programming
> languages and even PASSED on the border of these languages.

How? Please provide information. Including a proof that the runtimes of the
particular programming languages have deterministic behaviour and
semantics.

> I cannot disagree more. It is all but normal to allow operations to throw
> exceptions since operations (as any RPC mechanism) *are* the bit that
> component-based systems borrow to these programming languages. Which is,
> indeed, one of the reasons why relying on operations should be limited to
> very special cases.

So, basically you _agree_ instead of disagreeing, since you say "relying on
operations should be limited to very special cases". I still miss a 100%
semantically calear and deterministic set of guidelines about what these
'special cases' might be, and why using exceptions in those cases is "best
practice".

> For other type of interaction with components, I do agree. Since
> component-based systems are *not* using the same paradigm than programming
> languages, events (such as state changes) are a better reporting mechanism.

This "component-based is not object-oriented" remark was exactly the gist
of my message :-) And since Orocos is a _component_ framework, I always
make this remark when messages appear on the mailinglist that want to
pollute the component-based paradigm with programming language-specific
idioms or semantics.

With our research work on the "BRICS Component Model", you can expect
even more such remarks about not using "established" object oriented programming
language primitives. For example, the concept of "the" API of a component
is going to fade away, being replaced (in data flow cases, for which
component based systems make lots of sense) by the configuration of the
data ports (and the computations behind those ports). For example, "the"
inverse dynamics algorithm will not exist anymore (at least not its API)
since there are tons of ways to use the computational pieces inside current
implementations of inverse/forward/hybrid dynamics; so many even that it is
meaningless to try to define a "complete API" for it. Same holds for
'control' and 'perception' components in robotics: what is "the" API of
SLAM? Or of "people tracking"? It's useless to try to define them because
SLAM and people tracking are full applications and not just class libraries
(as most people tend to think still). Instead, it's much better to support
developers in configuring the most appropriate composition of components
for a particular use case, on top of 100% reusable pieces.

Stay tuned... :-) BRICS will release the beta version of its "best
practices wikibook" somewhere in March.

Exceptions during Operation calls

On 01/25/2012 09:30 AM, Herman Bruyninckx wrote:
>> Exceptions have the same semantic in all modern programming languages.
>
> But you can't "serve" a Java exception in a C++ component... In other
> words, the _handling_ of exceptions as they are provided as programming
> language primitives is _not_ portable. So, it is not recommended to rely on
> them in a component based design. Simple.
Simply not true. The issue is not the exception mechanism or the
languages, but how you implement language boundaries. .NET does
translate exceptions across boundaries. So does rice (a C++-to-ruby
bindings mechanism). Or CORBA for that matter. It is *possible*, but
technically challenging (more on that later in this mail)

>>> So, at best, you will make a system that has a lock-in into RTT
>>> and C++. (And, to paraphrase Voltaire, even if you do not agree with me
>>> that an Orocos lock-in is a bad thing, I will fight for your right to
>>> think so :-))
>> Again, I don't see why. Exceptions are used heavily in a lot of
>> programming languages and even PASSED on the border of these languages.
>
> How? Please provide information. Including a proof that the runtimes of the
> particular programming languages have deterministic behaviour and
> semantics.
I can't give you a proof, but that's usually a keyword against anything
higher level than very very simple mechanisms. Which then make the
development of robust systems very hard to come by, as either (1) the
complexity of error handling is too high or (2) because formal methods
can't handle "normally-sized" systems.

The only thing I can give you is that, among the programming languageS I
use daily, exceptions *do* have consistent semantic and deterministic
behaviour.

>> I cannot disagree more. It is all but normal to allow operations to
>> throw exceptions since operations (as any RPC mechanism) *are* the bit
>> that component-based systems borrow to these programming languages.
>> Which is, indeed, one of the reasons why relying on operations should
>> be limited to very special cases.
>
> So, basically you _agree_ instead of disagreeing, since you say "relying on
> operations should be limited to very special cases". I still miss a 100%
> semantically calear and deterministic set of guidelines about what these
> 'special cases' might be, and why using exceptions in those cases is "best
> practice".
In my opinion, using exceptions for error handling in modern programming
languages is best practice. It makes the code a lot less complex, makes
sure that errors don't get overlooked, and ensures that you can handle
errors where it is relevant. 90% of "error handling" code in
non-exception-based programs is error passing (i.e. passing the error of
a subcall to the supercall).

Operations, as all RPC, *are* a "programming language" feature, not a
"component system" feature. Hence the "use exceptions inside those". The
issue, obviously, is technical: how to make sure that exceptions thrown
by the callee are properly passed to the caller in a generic way. It's
hard to come by technically (did I mention .NET ?), so, yes, in
practice, my take on operations-that-throw-exceptions would be to
convert them *at the component boundaries* in a state change of the
component (e.g. the aptly named "exception" state). And report a
specific failure to the operation caller. Which can then do whatever it
wants (including throwing an exception in its own language). Which is
already what the other state hooks do, by the way.

As for the "special cases", operations in Rock are used ONLY for
configuration where using properties are not and configure/start/stop
cycle. Not for runtime synchronization between components.

> With our research work on the "BRICS Component Model", you can expect
> even more such remarks about not using "established" object oriented
> programming
> language primitives. For example, the concept of "the" API of a component
> is going to fade away, being replaced (in data flow cases, for which
> component based systems make lots of sense) by the configuration of the
> data ports (and the computations behind those ports).
+1. That's what I advocate for years -- and what is extensively deployed
in Rock's system management layer, but let's say that the community take
on that is ... pretty cold.

> Stay tuned... :-) BRICS will release the beta version of its "best
> practices wikibook" somewhere in March.
Well, since I'm already doing all of that I'm not holding my breath ;-)

Exceptions during Operation calls

On Wed, 25 Jan 2012, Sylvain Joyeux wrote:

> On 01/25/2012 09:30 AM, Herman Bruyninckx wrote:
>>> Exceptions have the same semantic in all modern programming languages.
>>
>> But you can't "serve" a Java exception in a C++ component... In other
>> words, the _handling_ of exceptions as they are provided as programming
>> language primitives is _not_ portable. So, it is not recommended to rely on
>> them in a component based design. Simple.
> Simply not true. The issue is not the exception mechanism or the languages,
> but how you implement language boundaries. .NET does translate exceptions
> across boundaries. So does rice (a C++-to-ruby bindings mechanism). Or CORBA
> for that matter. It is *possible*, but technically challenging (more on that
> later in this mail)

And, more importantly, the exact semantics is hidden in the runtime!
Whether you add one extra (as in your .NET example) or not does not make a
difference for the points I want to stress: semantic clarity and
determinism of the behaviour.

>>>> So, at best, you will make a system that has a lock-in into RTT
>>>> and C++. (And, to paraphrase Voltaire, even if you do not agree with me
>>>> that an Orocos lock-in is a bad thing, I will fight for your right to
>>>> think so :-))
>>> Again, I don't see why. Exceptions are used heavily in a lot of
>>> programming languages and even PASSED on the border of these languages.
>>
>> How? Please provide information. Including a proof that the runtimes of the
>> particular programming languages have deterministic behaviour and
>> semantics.
> I can't give you a proof, but that's usually a keyword against anything
> higher level than very very simple mechanisms. Which then make the
> development of robust systems very hard to come by, as either (1) the
> complexity of error handling is too high or (2) because formal methods can't
> handle "normally-sized" systems.

Indeed. Robustness should not come from your programming language runtime,
but from the _human developer_ using (i) knowledge about the application,
and (ii) solutions that prevent error handling to explode (and the latter
is stimulated implicitly by offering an "exception handling" support). In
other words: don't rely on your programming languages, but on your system
coordination. Easy to say, difficult to achieve.

> The only thing I can give you is that, among the programming languageS I use
> daily, exceptions *do* have consistent semantic and deterministic behaviour.

Where can I find the doumentation about this?

>>> I cannot disagree more. It is all but normal to allow operations to
>>> throw exceptions since operations (as any RPC mechanism) *are* the bit
>>> that component-based systems borrow to these programming languages.
>>> Which is, indeed, one of the reasons why relying on operations should
>>> be limited to very special cases.
>>
>> So, basically you _agree_ instead of disagreeing, since you say "relying on
>> operations should be limited to very special cases". I still miss a 100%
>> semantically calear and deterministic set of guidelines about what these
>> 'special cases' might be, and why using exceptions in those cases is "best
>> practice".
> In my opinion, using exceptions for error handling in modern programming
> languages is best practice. It makes the code a lot less complex, makes sure
> that errors don't get overlooked, and ensures that you can handle errors
> where it is relevant. 90% of "error handling" code in non-exception-based
> programs is error passing (i.e. passing the error of a subcall to the
> supercall).

You are thinking in the "one programming language" and "compile time
system building" paradigms; I am not. _And_ it's not the fact that your
programming languages has support for exceptions that makes your code less
complex, but _how_ the _human developer_ is using that concept. The same
"best practice" approach will also work if you replace exceptions by
explicit events, which is more portable in a "multi-vendor" component based
paradigm.

> Operations, as all RPC, *are* a "programming language" feature, not a
> "component system" feature. Hence the "use exceptions inside those". The
> issue, obviously, is technical: how to make sure that exceptions thrown by
> the callee are properly passed to the caller in a generic way. It's hard to
> come by technically (did I mention .NET ?), so, yes, in practice, my take on
> operations-that-throw-exceptions would be to convert them *at the component
> boundaries* in a state change of the component (e.g. the aptly named
> "exception" state). And report a specific failure to the operation caller.
> Which can then do whatever it wants (including throwing an exception in its
> own language). Which is already what the other state hooks do, by the way.

The key phrase in your paragraph above is 'at the component boundaries'!
That means that you consider your current component implementations as the
lowest level of reuse. I am more ambitious, in that I want to "recurse"
into components indefinitely, and make all the inner levels of composition
reusable.

> As for the "special cases", operations in Rock are used ONLY for
> configuration where using properties are not and configure/start/stop cycle.
> Not for runtime synchronization between components.

I agree with you that this is a motivated 'special case'. It's the _only_
one that I have seen until now. So, if you know more of them, it would be
very relevant information. Because I like the fact that we can _enumerate_
all special cases, and explain them. Because that would help newcomers to
get some guidance; a lot more guidance than a statement saying "don't use
this except in some special cases", because that's not really helping
people.

Within the BRICS context, an effort is under way to make such a list of
documented use cases. And that's where community inputs will be sollicited
most actively. The hope is to come to a repository where the 'special
cases' are exhaustively identified and documenten.

>> With our research work on the "BRICS Component Model", you can expect
>> even more such remarks about not using "established" object oriented
>> programming
>> language primitives. For example, the concept of "the" API of a component
>> is going to fade away, being replaced (in data flow cases, for which
>> component based systems make lots of sense) by the configuration of the
>> data ports (and the computations behind those ports).

> +1. That's what I advocate for years -- and what is extensively deployed in
> Rock's system management layer, but let's say that the community take on that
> is ... pretty cold.

Yes, not surprisingly, given the "lock in" in the "we have to make an API
for everything" in our current computer science curricula.

But my hope of changing this cold reception is via the above-mentioned list
of "best practice" use cases: showing people working examples, with a
motivation why they are good, can become the "de facto" way of introducing
a paradigm shift in the community. That's my hope...

>> Stay tuned... :-) BRICS will release the beta version of its "best
>> practices wikibook" somewhere in March.
> Well, since I'm already doing all of that I'm not holding my breath ;-)

You are one of the number one targets on our "external contributors" list,
_because_ you have so much experience with "best practices"! :-)
BRICS can even offer you some money to work on this, as a "BRICS
internship". Interested? Other serious takers?

> Sylvain Joyeux (Dr.Ing.)

Herman

> Space & Security Robotics
>
> !!! Achtung, neue Telefonnummer!!!
>
> Standort Bremen:
> DFKI GmbH
> Robotics Innovation Center
> Robert-Hooke-Straße 5
> 28359 Bremen, Germany
>
> Phone: +49 (0)421 178-454136
> Fax: +49 (0)421 218-454150
> E-Mail: robotik [..] ...
>
> Weitere Informationen: http://www.dfki.de/robotik
> -----------------------------------------------------------------------
> Deutsches Forschungszentrum fuer Kuenstliche Intelligenz GmbH
> Firmensitz: Trippstadter Straße 122, D-67663 Kaiserslautern
> Geschaeftsfuehrung: Prof. Dr. Dr. h.c. mult. Wolfgang Wahlster
> (Vorsitzender) Dr. Walter Olthoff
> Vorsitzender des Aufsichtsrats: Prof. Dr. h.c. Hans A. Aukes
> Amtsgericht Kaiserslautern, HRB 2313
> Sitz der Gesellschaft: Kaiserslautern (HRB 2313)
> USt-Id.Nr.: DE 148646973
> Steuernummer: 19/673/0060/3
> -----------------------------------------------------------------------
>

--
KU Leuven, Mechanical Eng., Mechatronics & Robotics Research Group
<http://people.mech.kuleuven.be/~bruyninc> Tel: +32 16 328056
EURON Coordinator (European Robotics Research Network) <http://www.euron.org>
Open Realtime Control Services <http://www.orocos.org>
Associate Editor JOSER <http://www.joser.org>, IJRR <http://www.ijrr.org>