[Up: C++ mapping]
[Previous: Modules] [Next: Time Service]

Subsections

- CORBA Compliant Exception Handling
- MICO Specific Exception Handling
- No Exception handling

# Exceptions

Due to the limited support for exceptions in earlier versions of the GNU C++ compiler (namely gcc 2.7.2) MICO supports several kinds of exception handling:

- CORBA compliant exception handling
- MICO specific exception handling
- no exception handling

Two common problems with exception handling are ``catching by base classes'' and ``exceptions in shared libraries'':

- catching by base classes: when throwing exception `X` it should be possible to catch it by specifying a base class of `X` in the catch clause. Some compilers (noteably gcc 2.7) do not support this.
- exceptions in shared libraries: throwing an exception from a shared library into non shared library code does not work with some compilers on some platforms (gcc 2.7, gcc 2.8 and egcs 1.x on some platforms).

Which kind of exception handling is used is determined by the capabilities of the C++ compiler and command line options passed to the `configure` script. By default CORBA compliant exception handling will be selected if the C++ compiler supports catching by base classes, otherwise MICO specific exception handling is selected if the compiler supports exception handling at all. If exceptions in shared libraries do not work then no exception handling is selected for code in shared libraries. You can enforce MICO specific exception handling by specifying `-disable-std-eh` as a command line option to `configure`. You can disable exception handling by specifying `-disable-except` as a command line option to `configure`.

You can find out about the exception handling support of your MICO binaries by running the IDL-Compiler with the `-config` command line option:

      $ idl --config
      MICO version: 2.2.7
      supported CORBA version: 2.2
      exceptions: CORBA compliant
      modules are mapped to: namespaces
      STL is: miniSTL
      SSL support: no
      loadable modules: yes

The following sections go into detail about each of the exception handling modes supported by MICO.

## CORBA Compliant Exception Handling

As the name already indicates this exception handling mode is conformant to the CORBA specification. You can use `throw` to throw exceptions. Exceptions are caught by specifying the exact type or one of the base types of the exception. Here are some examples:

      // throw CORBA::UNKNOWN exception
      throw CORBA::UNKNOWN();

      // catch CORBA::UNKNOWN exception
      try {
        ...
      } catch (CORBA::UNKNOWN &ex) {
        ...
      }

      // catch all system exceptions (including CORBA::UNKNOWN)
      try {
        ...
      } catch (CORBA::SystemException &ex) {
        ...
      }

      // catch all user exceptions (wont catch CORBA::UNKNOWN)
      try {
        ...
      } catch (CORBA::UserException &ex) {
        ...
      }

      // catch all exceptions (including CORBA::UNKNOWN)
      try {
        ...
      } catch (CORBA::Exception &ex) {
        ...
      }

If an exception is thrown but not caught MICO will print out a short description of the exception and terminate the process.

## MICO Specific Exception Handling

This kind of exception handling has been invented for C++ compilers that do not support catching by base classes. For example it is quite common to catch all system exceptions. Since catching `CORBA::SystemException &` does not work one would have to write one catch clause for each of the 30 system exceptions. To work around this problem the function `mico_throw()` and special `_var` types have been introduced.

You must not use the `throw` operator directly to throw an exception, instead you should use the function `mico_throw()` defined in `mico/throw.h`, which is automatically included by IDL compiler generated code:

      // ok
      mico_throw (CORBA::UNKNOWN());

      // wrong
      throw CORBA::UNKNOWN();

will throw the CORBA system exception `UNKNOWN`. User defined exceptions are thrown the same way.

Exceptions are always caught by reference using the `_var` types. System exceptions must be caught by `SystemException_var`:

      // ok
      try {
        ...
        mico_throw (CORBA::UNKNOWN());
        ...
      } catch (CORBA::SystemException_var &ex) {
        ...
      }

      // wrong
      try {
        ...
        mico_throw (CORBA::UNKNOWN());
        ...
      } catch (CORBA::UNKNOWN_var &ex) {
        ...
      }

      // wrong
      try {
        ...
        mico_throw (CORBA::UNKNOWN());
        ...
      } catch (CORBA::Exception_var &ex) {
        ...
      }

Sometimes it is necessary to know exactly which system exception has been thrown:

      // ok
      try {
        ...
        mico_throw (CORBA::UNKNOWN());
        ...
      } catch (CORBA::SystemException_var &sys_ex) {
        if (CORBA::UNKNOWN *ukn_ex = CORBA::UNKNOWN::_narrow (sys_ex)) {
          // something1
        } else {
          // something2
        }
      }

      // wrong
      try {
        ...
      } catch (CORBA::UNKNOWN_var &ukn_ex) {
        // something1
      } catch (CORBA::SystemException_var &other_ex) {
        // something2
      }

In contrast to system exceptions a user exception `X` must be caught by `X_var` (i.e., not by `UserException_var`):

      // ok
      try {
        ...
        mico_throw (SomeExcept());
        ...
      } catch (SomeExcept_var &some_ex) {
        ...
      }

      // wrong
      try {
        ...
        mico_throw (SomeExcept());
        ...
      } catch (CORBA::UserException_var &usr_ex) {
        ...
      }

      // wrong
      try {
        ...
        mico_throw (SomeExcept());
        ...
      } catch (CORBA::Exception_var &ex) {
        ...
      }

It is possible to write code that works both with CORBA compliant exception handling and MICO specific exception handling. For this one should follow the instructions in this section but replace `_var` by `_catch`. In MICO specific exception handling mode `X_catch` is typedef'ed to `X_var`, in CORBA compliant exception handling mode `X_catch` is typedef'ed to `X`. Furthermore each exception `X` provides an overloaded `->` operator so that you can use `->` to access the exception members in the catch body independent of the exception handling mode. Here is an example:

      // throw
      mico_throw (CORBA::UNKNOWN());

      // catch
      try {
        ...
      } catch (CORBA::SystemException_catch &ex) {
        cout << ex->minor() << endl;
      }

If an exception is thrown but not caught MICO will print out a short description of the exception and terminate the process.

## No Exception handling

Some C++ compilers do not properly support exceptions in shared libraries, others do not support exceptions at all. In these cases exception handling is not available in shared libraries or not available at all, respectively.

Exception handling related C++ keywords (`try`, `throw`, `catch`) cannot be used in this mode. `mico_throw()` can be used but will only print out a short description of the passed exception and terminate the process.

[Previous: Modules] [Next: Time Service]
[Up: C++ mapping]