5.2. Handling Errors

The ML provides some functionality for handling errors on different levels. Generally, programmers should not try to handle errors themselves. It is strongly recommended to call the correct handler and leave error handling to the ML.

It is possible to configure the ML so that the application handles errors in different ways: the application could, for instance, generate an e-mail message, or it could terminate, or it could pop up a window and try to continue. The way how applications handle errors should be configured globally for the ML and not for the individual modules.

So, how to handle an error or a warning? There are three macros to be called on warnings, errors or fatal errors:

  1. mlWarning(functionName, errorCode)

    This macro is used to print warning messages which notify the user or application of any type of (non-urgent) errors or abnormalities. See number 3 for parameter descriptions.

  2. mlError(functionName, errorCode)

    This macro is used to print errors messages which notify the user or the application of errors that cause incorrect program calculations but that do not lead to program termination, i.e., the system tries to continue processing. However, these errors may lead to fatal errors later. See number 3 for parameter descriptions.

    [Important]Important

    Do not terminate the program! Leave this decision to the error handling routines of the ML!

  3. mlFatalError(functionName, errorCode)

    This macro is used to print error messages which notify the user or the application of fatal errors that make it impossible to continue without getting into an invalid program state.

    [Important]Important

    Do not terminate the program! Leave this decision to the error handling routines of the ML!

    The functionName string identifies the calling function, including the class name such as "Host::getTile()". The errorCode is an MLErrorCode or a string that describes the problem such as ML_BAD_DATA_TYPE, ML_NO_MEMORY or ML_PROGRAMMING_ERROR. Finally the most important thing is that each of the macros returns a stream object which can be used to provide futher information on the problem. This has the advantage that a complex information string can be streamed into the macro instead of having to create a string by manually.

    [Note]Note

    You are not responsible for the program to continue safely after a fatal error, just explain what you do even if it will lead to a crash.

    This is necessary since fatal error management depends on the configuration of the ML error handler. The error handler might try to continue the code normally, or to terminate the program, or to jump into a debugger, to send a mail, to throw an exception or something else. If you terminate the process, the ML will not be able to handle it.

  4. mlInfo(functionName)

    This macro is used to print any type of non-debugging information to the error handler of the ML. The macro is typically used for important log information that are not warnings or error messages but that are important for application analysis, e.g., after a crash. It returns a stream object which is used to construct the information string.

    [Important]Important

    To avoid the application and MeVisLab log files being filled with useless information during normal operation, do not use this macro for debugging purposes. Use the appropriate mlDebug macros instead.

Below you can see some examples that illustrate how to make use of the macros. You can stream any object that supports to be streamed to a std::stream into the result message.

mlWarning("SomeObject::someFunction", ML_BAD_PARAMETER) \
  << "The passed parameter " << someIndex << " is out of range.";

mlError("SomeObject::someFunction", ML_NO_MEMORY) \
  << "Could not allocate image of size " << someExtent << ".";

mlInfo("SomeObject::someFunction") << "Finished registration, result matrix is " << someMatrix;