Wtx ~ Wt Extension Library
WtxLib
Exceptions Notification

During the course of development, Wt will throw exceptions under various conditions. It is exceedingly helpful to know what the exceptions are and at what point they occurred. It is possible to hook in to the main application loop to catch the exceptions and print a diagnostic.

The documentation for the hook can be found here (link may be out of date):

https://www.webtoolkit.eu/wt/doc/reference/html/classWt_1_1WApplication.html#a4a6f167bea94aefa8ba24f914c2fbee5

Set up the following in your main application class

Hooking Application Notification
void BaseApp::notify( const Wt::WEvent & event )
{
/*
** Build a list of expected exceptions. One in particular is if
** the client browser session times-out. This will cause the
** session to be killed automatically by Wt. This is an expected
** exception, so it goes on the list of exceptions to the exceptions.
**
*/
static std::vector<std::string> exceptions =
{
"session was killed",
"all threads are busy"
};
static std::vector<std::string> pop_exceptions =
{
"basic_string::at: __n", // this happens when a <space> is put after the time in a WTimeEdit field
"bad lexical cast" // this happens when a '' nothing character is put where a number '0' is expected
};
/*
** Try to notify the main application loop.
*/
try
{
Wt::WApplication::notify(event);
}
/*
** Handle the application exception.
*/
catch( std::exception & exception )
{
/*
** If this is an expected exception, then ignore it. It just means
** it's a dead session, that we don't really care about.
*/
for( auto except : exceptions )
if( std::string(exception.what()).find(except) != std::string::npos )
{
COUT_( "redirecting to: " + originalUrl( internalPath() ) );
redirect( originalUrl( internalPath() ) );
quit();
return;
}
/*
** prepare a message that we can send to the logs
**
*/
auto message =
Wt::WString("EXCEPTION: '{1}'")
.arg( exception.what() )
.toUTF8()
;
/*
** Log the exception, and display it to the console as well.
** Note that if you also are logging field-level-changes and
** during one of those changes an exception is thrown, then
** even if the exception does not reveal much about what
** the source of the failure was, the log may contain everything
** that was going on right before the exception was thrown.
**
*/
txtLog( message, true );
/*
** This may be an exception that we just want to pop-up
** to the user.
**
*/
for( auto except : pop_exceptions )
if( std::string(exception.what()).find(except) != std::string::npos )
{
Wt::WMessageBox::show
(
"Exception",
"<center>"
" Oh oh, something went wrong,<br />"
" please check what you are editing "
" and try again"
"</center>"
, Wt::Ok
);
return;
}
COUT_( "\n\n\n\n\n\n<<<<< EXCEPTION >>>>>>>" );
COUT_( exception.what() );
/*
** This exception was not expected, so send a text message to an administrator
** that can hopefully deal with it.
**
*/
auto result =
system
(
emailText
(
"exception",
message,
{"adminemail@somesuchthing.com"}
).c_str()
);
(void)result;
/*
** since this is a fatal exception, just refresh the app so that
** everything properly reloads.
**
*/
COUT_( "redirecting to: " + originalUrl( internalPath() ) );
redirect( originalUrl( internalPath() ) );
quit();
} // endcatch( std::exception & exception )
} // endvoid CCB::BaseApp::notify( const Wt::WEvent & event )