examples/errors/ turns three messages into the three ways a program reports trouble.
The message file
# errors.msg — messages that are errors: an exception class with a throw
# function, a fatal error function and a syslog function.
$MODULE errors
$NAMESPACE app :: errors
$LANGUAGE en
# ConfigMissingException derives from std::exception (publicly, the
# default); ThrowConfigMissing( path ) throws it. what() returns the text.
$EXCEPTION INHERITED std::exception
$THROW ENABLE
$MESSAGE ConfigMissing
@ path std::string const &
"configuration file '{$path}' is missing"
[tr]
"yapılandırma dosyası '{$path}' bulunamadı"
# FatalError( code ) prints the text on std::cerr and runs the EXIT statement.
$THROW DISABLE
$ERROR ENABLE
$ERROR EXIT std::exit( 2 )
$ERROR PREFIX Fatal
$MESSAGE Error
@ code int
|fatal error {$code}, giving up
[tr]
|ölümcül hata {$code}, vazgeçiliyor
# LogStarted( pid ) sends the text to syslog, by default as LOG_DAEMON | LOG_NOTICE.
$ERROR DISABLE
$SYSLOG ENABLE
$SYSLOG FACILITY DAEMON
$SYSLOG LEVEL NOTICE
$MESSAGE Started
@ pid long
"started, pid {$pid}"
[tr]
"başladı, süreç {$pid}"
The settings are sticky, so the file reads top to bottom: $THROW is on for ConfigMissing only, $ERROR for Error only, $SYSLOG for Started. $ERROR PREFIX Fatal replaces both of $ERROR's defaults — Error + Error becomes FatalError, not FatalErrorError.
The program
#include "errors.hh"
#include <cstring>
#include <fstream>
#include <iostream>
#include <unistd.h>
namespace
{
void Load( std::string const &path )
{
std::ifstream file( path );
if ( ! file )
{
app::errors::ThrowConfigMissing( path );
}
}
}
int main( int argc, char **argv )
{
// Only when asked: the smoke test does not write to the system log.
if ( argc > 1 && std::strcmp( argv[1], "--syslog" ) == 0 )
{
app::errors::LogStarted( static_cast<long>( getpid( ) ) );
}
try
{
Load( "/nonexistent/app.conf" );
}
catch ( std::exception const &e )
{
std::cout << "caught: " << e.what( ) << std::endl;
}
app::errors::FatalError( 7 ); // does not return: std::exit( 2 )
}
Output
caught: configuration file '/nonexistent/app.conf' is missing
fatal error 7, giving up
The first line is what() of the exception; the second is FatalError writing to std::cerr before std::exit( 2 ) — the smoke test checks both lines and the exit code 2. LogStarted runs only with --syslog, so the test does not write to the system log.
What was generated
class ConfigMissingException : public std::exception { ... };
[[noreturn]] void ThrowConfigMissing( std::string const & path, std::locale const &loc );
[[noreturn]] void ThrowConfigMissing( std::string const & path );
void FatalError( int code, std::locale const &loc );
void FatalError( int code );
void LogStarted( long pid, std::locale const &loc, int option_parameter = LOG_DAEMON | LOG_NOTICE );
void LogStarted( long pid, int option_parameter = LOG_DAEMON | LOG_NOTICE );

