3.20 DM_ErrorHandler

Mit dieser Funktion kann eine Handlerfunktion eingerichtet werden, die beim Auftreten eines Fehlers, welcher vom Regelinterpreter erkannt wird, aufgerufen wird.

DM_Boolean DML_default DM_EXPORT DM_ErrorHandler
(
  DM_ErrorHandlerProc  funcp,
  DM_UInt     operation,
  DM_Options  options
)

Parameter

-> DM_ErrorHandlerProc funcp

Dieses ist ein Zeiger auf die Funktion, die als Fehlerhandler installiert werden soll.

-> DM_UInt operation

In diesem Parameter wird die Aktion angegeben, die ausgeführt werden soll. Dabei gibt es folgende Werte:

DMF_RegisterHandler

Handlerfunktion soll installiert werden

DMF_EnableHandler

Handlerfunktion soll wieder aufgerufen werden

DMF_DisableHandler

Handlerfunktion soll nicht mehr ausgerufen werden

DMF_WithdrawHandler

Handlerfunktion soll abgemeldet werden

-> DM_Options options

Zurzeit unbenutzt, muss 0 sein.

Rückgabewert

DM_TRUE

Aktion erfolgreich.

DM_FALSE

Aktion konnte nicht durchgeführt werden.

Dies kann Auftreten, wenn durch die Aktion der Handler zweimal existieren würde, der Funktionspointer NULL ist oder der von der Aktion angesprochene Handler nicht gefunden werden konnte.

Ein nicht abgefangener Fehler im Regelcode der Anwendung (z.B. fehlerhafte Parametertypen, dynamischer Zugriff auf ein nicht vorhandenes Attribut oder relatives Kind, jeweils nicht über fail() abgefangen) wird vom Regelinterpreter, als EVAL ERROR in die Log- oder Tracedatei geschrieben. Meldungen in [] die mit W:, E: oder I: anfangen wie Modul- bzw. Interface-Ladefehler gehören nicht zum Regelinterpreter und werden insofern auch nicht an den Fehlerhandler weitergeleitet.

Um es IDM-Anwendungen zu ermöglichen über diese Anwendungsfehler vorher informiert zu werden, dient der Fehlerhandler. Mehrere, nicht identische, Fehlerhandler sind möglich. Wobei der Aufruf in umgekehrter Reihenfolge des Anmeldens erfolgt. Nur die aktivierten Fehlerhandler werden aufgerufen und erhalten dabei die gleiche Informationsstruktur (DM_ErrorInfo) als Parameter mit. Diese Aufrufe werden in die Trace-Datei mitprotokolliert. Ein rekursiver Aufruf der Fehlerhandler wird unterbunden. Ein Aufruf der DM_ErrorHandler-Funktion innerhalb eines Fehlerhandlers darf keine neuen Handler installieren oder deinstallieren.

Es ist zu bedenken, dass der Fehlerhandler synchron aufgerufen wird und insofern Design und Kodierung mit besonderer Sorgfalt und unter Berücksichtigung der entsprechenden Konstellationen und Restriktionen erfolgen muss. So ist durchaus ein Aufruf der Handler vor dem Start des Dialoges möglich (z.B. wenn Fehler in :init()-Methoden vorliegen) wie auch bei unsachgemäßer Benutzung in einem ungeeigneten Runstate (z.B. erzwungener Aufruf einer fehlerhaften Regel durch DM_CallRule innerhalb einer Formatfunktion). Eine Vermeidung solcher Konstellationen ist sinnvoll. Auch sollte, wenn der IDM für die Darstellung einer Fehlerbox verwendet wird, ein eigenständiger, vor der Anwendung gestarteten, Fehlerdialog benutzt werden.

Die zu installierende Fehlerhandler-Funktion muss dabei wie folgt definiert sein:

typedef void (DML_default DM_CALLBACK *DM_ErrorHandlerProc) __((DM_ErrorInfo *info));

Die mitgegebene Informationsstruktur gibt dabei Auskunft über den Fehler:

define  EITK_rule_engine  1

typedef struct {
  /* user info, not changeable */
  DM_UInt1      task;     /* task/component which detects the error */
  DM_ErrorCode  errcode;  /* error code */
  DM_ID         object;   /* this object or null-ID */
  DM_ID         rule;     /* rule where error occured */
  DM_String     file;     /* module/dialgo filename or NULL */
  DM_String     message;  /* error message or NULL*/
} DM_ErrorInfo;

Diese Informationen dürfen von keinem Fehlerhandler verändert werden.

Strings liegen grundsätzlich in der Applikations-Codepage vor.

Der task-Eintrag gibt Auskunft über die IDM-Komponente, die den Fehler meldet, und sollte wegen möglichen zukünftigen Erweiterungen immer überprüft werden. Momentan werden nur Fehler vom Regelinterpreter als EITK_rule_engine weitergegeben.

Die Einträge geben Auskunft über den Fehlercode, die Regel in der der Fehler aufgetreten ist sowie den dazugehörigen Fehlertext. Wenn möglich, wird das this-Objekt sowie der Dateiname des Moduls bzw. Dialogs, in dem sich die fehlerhafte Regel befindet, bereitgestellt.

Beispiel

#include <IDMuser.h>
void DML_default DM_CALLBACK ErrorHandler __1((DM_ErrorInfo *, info))
{
  if (info->task == EITK_rule_engine)
  {
    DM_TraceMessage("ERROR: errcode=%d message=\"%s\" rule=\"$I\"",
      DMF_LogFile|DMF_Printf,
      info->errcode, info->message,
      info->rule);
  }
}
int DML_c DM_CALLBACK AppMain (int argc, char **argv)
{
  DM_ID dialogID = (DM_ID)0;
  if (DM_Initialize (&argc, argv, 0) == FALSE)
    return (1);
  if (argc>1)
  {
    if (!(dialogID = DM_LoadDialog (argv[1], 0)))
      return (1);
    DM_ErrorHandler(ErrorHandler, DMF_RegisterHandler, 0);
    DM_StartDialog (dialogID, 0);
    DM_EventLoop (0);
    return (0);
  }
  return 1;
}