Provided by: elektra-doc_0.8.14-5_all

#### NAME

       elektra-error-handling - error handling in Elektra



#### Terminology

       It is sometimes unavoidable that errors occur that ultimately have an impact for the user.
Examples for such an error are that hard disc space is exhausted.  For  a  library  it  is
necessary  to  pass  information about the facts and circumstances to the user because the
user wants to  be  informed  why  a  requested  action  failed.  So  Elektra  gathers  all
information  in these situations. We call this resulting information error information and
warning information depending on the severity.

If the occurred error is  critical  and  ultimately  causes  a  situation  that  the  post
conditions  cannot  be  fulfilled  we  say  that Elektra comes into a faulty state. Such a
faulty state will change the control flow inside Elektra completely. Elektra is unable  to
resolve  the problem without assistance. After cleaning up resources, a faulty state leads
to immediate return from the function with an  error  code.  As  a  user  expects  from  a
library,  Elektra  never  calls  exit()  or something similar, regardless of how fatal the
error is. In this situation error information should be set.

On the other hand, for many  problems  the  work  can  go  on  with  reasonable  defaults.
Nevertheless,  the  user  will  be  warned  that  a  problem  occurred  using  the warning
information. These situations do not influence the  control  flow.  But  applications  can
choose  to  react  differently  in  the  presence  of warning information. They may not be
interested in any warning information at all. It is no problem if warning  information  is
ignored  because  they  are  stored  and  remain  accessible  in  a  circular  buffer. The
implementation prevents an overflow  of  the  buffer.  Instead  the  oldest  warnings  are
overwritten.

When  error or warning information is presented to the user, it is called error message or
warning message. The user may reply to this message in which way to continue.

Error vs. Warning Information
When an error in an faulty state  occurs,  the  error  information  must  still  hold  the
original  error  information.  So  even  in  problems  that  would  cause  a faulty state,
otherwise, the error information must be omitted or transformed to a warning  information.
In some places only the adding of warning information is possible:

·   The  main  purpose  of  kdbClose()  is  to  free  the handle. This operation is always
successful and is carried  out  even  if  some  of  the  resources  cannot  be  freed.
Therefore, in kdbClose(), setting error information is prohibited. Warning information
is, however, very useful to tell the user the circumstance that  some  actions  during
cleanup failed.

·   Also  in  kdbOpen(),  only  adding warning information is allowed. If kdbOpen() is not
able to open a plugin, the affected backend will be dropped out. The user is certainly
interested  why  that  happened.  But  it  was decided not to make it an faulty state,
because the application might not even access the faulty part of the key hierarchy. An
exception  to  this  rule  is  if  kdbOpen()  fails  to open the default backend. This
situation will induce an faulty state.

·   In kdbSet(), the cleaning up of resources involves calling plugins.  But  during  this
process  Elektra  is  in  a  faulty  state,  so  only adding of warning information is
allowed. This ensures that the original error information is passed unchanged  to  the
user.

On the other hand, any access to the key database can produce warning information. Plugins
are allowed to yield warning information at any place and for any reason. For example, the
storage  plugin  reading  a  configuration  file with an old syntax, is free to report the
circumstance as warning information. Warning information is also useful when more than one
fact needs to be reported.



#### ErrorInformation

   Reporting Errors
Reporting errors is a critical task. Users expect different aspects:

·   The  \emph{user  of the application} does not want to see any error message at all. If
it is inevitable, he or she wants little, but very concrete information, about what he
or  she  needs  to do. The message should be short and concise. Some error information
may already be captured by the application,  but  others  like  ´´no  more  free  disk
space´´  have to be displayed. Conflicts should also be presented to the user. It is a
good idea to ask how to proceed if a diversity of possible reactions exists.  In  case
of conflicts, the user may have additional knowledge about the other program which has
caused the problem. The user is more likely to decide correctly by which strategy  the
configuration shall be restored.

·   The  \emph{user  of  the  library}  wants more detailed information. Categories of how
severe the error is can help to decide how to proceed.  Even  more  important  is  the
information  if  it  makes  sense  to  try  the same action again. If, for example, an
unreliable network connection or file system is used, the same action can  work  in  a
second try.

·   A  \emph{developer  of the library}\footnote{Library refers to both Elektra´s core and
plugins.} wants full information about anything needed to be  able  to  reproduce  and
locate  potential bugs. Ideally the error information should even mention the file and
line where the error occurred. This can help developers to decide if there  is  a  bug
inside Elektra or if the problem lies somewhere else.

·   Vast  information  is  needed  to support correct error handling in \empha[programming
language]{other programming languages}.  In  languages  supporting  exceptions,  class
name,  inheritance  or  interface  information  may  be  necessary.  Language specific
extensions are, however, not limited to exceptions. Other ways of handling errors  are
continuations  or  longjmp  in  C.  A  plugin  is  free  to  add, for example, jmp_buf
information to the error information.

It is certainly not a good idea to put all this previously mentioned  information  into  a
single string. Elektra chooses another way described in the next chapter.

As  stated  above, a library always informs the user about what has happened, but does not
print or log anything itself. One way to return an error information is to add a parameter
containing  the  error  information. In the case of Elektra, all KDB methods have a key as
parameter. This key is additionally passed to every plugin. The idea is to add  the  error
and warning information as metadata to this key. This approach does not limit flexibility,
because a key can hold a potentially unlimited number of metakeys.

The error information is categorised in metadata as follows:

·   [error] indicates that an faulty state is present. The value of the  metakey  contains
the  name  of  all  the  subkeys  that  are used for error indication. Metakeys do not
guarantee any particular order on  iteration.  Instead  the  user  can  find  out  the
information by looking at this metavalue.

Additional metakeys yield all the details.

·   [error/number] yields a unique number for every error.

·   [error/description]  is  a  description for the error to be displayed to the user. For
example, the metavalue can hold the text ´´could not write to file´´.

·   [error/reason] specifies the reason of the error. The human readable message is in the
metavalue  of  error/reason.  It  states why the error occurred. One example for it is
´´no disc space available´´.

·   [error/ingroup] contains ´´kdb´´ if the error occurred inside the  core.  It  contains
´´module´´  if  the error happened while loading a module. The metavalue is ´´plugin´´
if the error information comes from a plugin.

·   [error/module] indicates the name of the specific module or plugin.

·   [error/file] yields the source file from where the error information comes.

·   [error/line] represents the exact line of that source file.

As we see, the system is powerful because any other text or information can be added in  a
flexible manner by using additional metakeys.

Error Specification
The  error  specification in Elektra is written in simple colon-separated text files. Each
entry has a unique identifier and all the information we already discussed above. No  part
of Elektra ever reads this file directly. Instead it is used to generate source code which
contains everything needed to add a particular error or  warning  information.  With  that
file  we  achieved  a central place for error-related information. All other locations are
automatically generated instead of having error-prone duplicated code. This  principle  is
called ´´Don´t repeat yourself´´.

In  Elektra´s core and plugins, C macros are responsible for setting the error information
and adding warning information. In C only a macro is able to add the file  name  and  line
number of the source code. In language bindings other code may be generated.

Sources of Errors
Key  and  KeySet  functions  cannot expose more error information than the error code they
return. But, of course, errors are also possible in  these  functions.  Typically,  errors
concern  invalid  key names or null pointers. These problems are mostly programming errors
with only local effects.

The most interesting error situations,  however,  all  occur  in  KDB.  The  error  system
described  here is dedicated to the four main KDB functions: kdbOpen(), kdbGet(), kdbSet()
and kdbClose(). The place where the configuration is checked and made  persistent  is  the
source  of  most  error  information. At this specific place a large variety of errors can
happen ranging from opening, locking up and saving the file. Sometimes in plugins,  nearly
every line needs to deal with an error situation.



#### Exceptions

       Exceptions  are  a  mechanism  of  the  language  and  not  just an implementation detail.
Exceptions are not intended to  force  the  user  to  do  something,  but  to  enrich  the
possibilities.  In  this  section, we discuss two issues related to exceptions. On the one
hand, we will see how Elektra supports programming languages that provide  exceptions.  On
the  other  hand, we will see how the research in exceptions helps Elektra to provide more
robustness.

Language Bindings
C does not know anything about exceptions. But Elektra was designed so that  both  plugins
and  applications  can be written in languages that provide exceptions. One design goal of
Elektra´s error system is to transport exception-related information in a language neutral
way from the plugins to the applications. To do so, a language binding of the plugin needs
to catch every exception and transform it into error information and return an error code.

Elektra recognises the error code, stops the processing of plugins, switches to  a  faulty
state  and  gives  all  the  plugins  a  chance  to  do  the necessary cleanups. The error
information is passed to the application as usual. If the application is written in  C  or
does  not  want  to  deal  with exceptions for another reason, we are finished because the
application  gets  the  error  information  inside  metadata  as  expected.  But,  if  the
application  is  written  in another language, the binding translates the error code to an
exception and throws it. It is worth noting that the source and  target  language  do  not
need to be the same.

Such  a  system  needs a central specification of error information. We already introduced
such a specification file in error specification. The exception classes and converters can
be  generated  from  it.  An  exception  converter  is either a long sequence of try-catch
statements that transforms every  known  exception  into  an  appropriate  metakeys.  Each
exception  thrown by the plugin has to be caught. Alternatively, a converter can be a long
switch statement for every error number.  In  every  case  the  appropriate  exception  is
thrown.

The  motivation for using exceptions is that in C every return value has to be checked. On
the other hand, the C++ exception mechanism allows the programmer to throw an exception in
any  place and catch it where it is needed. So in C++ the code is not cluttered with parts
responsible for error handling. Instead, in a single place all exceptions of a plugin  can
be  transformed  to Elektra´s error or warning information. The code for this place can be
generated automatically using an exception converter.

Applications not written in C can also benefit from an  exception  converter.  Instead  of
using  the  metadata  mechanism,  the  error information can be converted to the exception
mechanism already used for that application. We see that Elektra is minimally invasive  in
this regard.

Exception Safety
We  can  learn from the way languages define the semantics for exception safety. Exception
safety is a concept which ensures that all resources are freed regardless  of  the  chosen
return  path.  Basic guarantees make sure that some invariants remain on an object even in
exceptional cases. On the other hand,  strong  guarantees  assure  that  the  investigated
operation  is successful or has no effect at all. Methods are said to be exception safe if
the object remains in a valid state. The idea of exception safety is  to  ensure  that  no
resource leaking is possible. kdbSet() written in C++ would look like:

try {
plugin[1].set(); // may throw plugin[2].set(); // may
throw plugin[3].set(); // may throw ...

plugin[PLUGIN_COMMIT].set(); // now all changes are
committed
} catch (...) {
// error situation, roll back the changes
plugin[1].error(); // does not throw plugin[2].error();
// does not throw plugin[3].error(); // does not throw ...

// now all changes are rolled back return -1;
} // now do all actions on success after commit
plugin[POSTCOMMIT].set(); // does not throw ...  return 1; //
commit successful

This  pseudo  code  is  much  clearer  than  the  corresponding C code. Let us explain the
guarantee Elektra provides using this example. One  by  one  plugin  gets  its  chance  to
process  the  configuration.  If any plugin fails, the semantics resemble that of a thrown
exception. All other plugins will not be executed. Instead, the plugins get  a  chance  to
recover  from  the  faulty state. In this catch part, the plugins are not allowed to yield
any error information, but they are allowed to add warnings.

Continue reading with the algorithm elektra-algorithm.md.

November 2015                 ELEKTRA-ERROR-HANDLING(7)