From 7dbd713731711d7d7c9a47b26376d6e8b33faeeb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 18 Nov 2010 14:10:15 +0000 Subject: [PATCH 1/1] Improve documentation about handling C++ exceptions in wx programs. Try to explain the different exception handling strategies more clearly in the overview and also update OnUnhandledException() documentation. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66205 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/doxygen/overviews/exceptions.h | 71 +++++++++++++++++------------ interface/wx/app.h | 24 ++++++---- 2 files changed, 58 insertions(+), 37 deletions(-) diff --git a/docs/doxygen/overviews/exceptions.h b/docs/doxygen/overviews/exceptions.h index 52f0d39ef0..83192f0cf0 100644 --- a/docs/doxygen/overviews/exceptions.h +++ b/docs/doxygen/overviews/exceptions.h @@ -28,10 +28,10 @@ wxWidgets, even using the exceptions in the user code was dangerous because the library code wasn't exception-safe and so an exception propagating through it could result in memory and/or resource leaks, and also not very convenient. -wxWidgets is exception-friendly. -It still doesn't use the exceptions by itself but it should be now safe to use the -exceptions in the user code and the library tries to help you with this. Please -note that making the library exception-safe is still work in progress. +However the recent wxWidgets versions are exception-friendly. This means that +while the library still doesn't use the exceptions by itself, it should be now +safe to use the exceptions in the user code and the library tries to help you +with this. @section overview_exceptions_strategies Strategies for exceptions handling @@ -42,35 +42,50 @@ any exceptions by itself and so you don't have to worry about exceptions at all unless your own code throws them. This is, of course, the simplest solution but may be not the best one to deal with all possible errors. -Another strategy is to use exceptions only to signal truly fatal errors. In -this case you probably don't expect to recover from them and the default -behaviour -- to simply terminate the program -- may be appropriate. If it is -not, you may override wxApp::OnUnhandledException() -in your wxApp-derived class to perform any clean up tasks. Note, however, that -any information about the exact exception type is lost when this function is -called, so if you need you should override wxApp::OnRun() and -add a try/catch clause around the call of the base class version. This would -allow you to catch any exceptions generated during the execution of the main -event loop. To deal with the exceptions which may arise during the program -startup and/or shutdown you should insert try/catch clauses in -wxApp::OnInit() and/or wxApp::OnExit() as well. - -Finally, you may also want to continue running even when certain exceptions -occur. If all of your exceptions may happen only in the event handlers of a -single class (or only in the classes derived from it), you may centralize your -exception handling code in wxApp::ProcessEvent -method of this class. If this is impractical, you may also consider overriding -the wxApp::HandleEvent() which allows you to handle -all the exceptions thrown by any event handler. +The next simplest strategy is to only use exceptions inside non-GUI code, i.e. +never let unhandled exceptions escape the event handler in which it happened. +In this case using exceptions in wxWidgets programs is not different from using +them in any other C++ program. + +Things get more interesting if you decide to let (at least some) exceptions +escape from the event handler in which they occurred. Such exceptions will be +caught by wxWidgets and the special wxApp::OnExceptionInMainLoop() method will +be called from the @c catch clause. This allows you to decide in a single place +what to do about such exceptions: you may want to handle the exception somehow +or terminate the program. In this sense, OnExceptionInMainLoop() is equivalent +to putting a @c try/catch block around the entire @c main() function body in +the traditional console programs. However notice that, as its name indicates, +this method won't help you with the exceptions thrown before the main loop is +started or after it is over, so you may still want to have @c try/catch in your +overridden wxApp::OnInit() and wxApp::OnExit() methods too, otherwise +wxApp::OnUnhandledException() will be called. + +Finally, notice that even if you decide to not let any exceptions escape in +this way, this still may happen unexpectedly in a program using exceptions as a +result of a bug. So consider always overriding OnExceptionInMainLoop() in your +wxApp-derived class if you use exceptions in your program, whether you expect +it to be called or not. In the latter case you may simple re-throw the +exception and let it bubble up to OnUnhandledException() as well. + +To summarize, when you use exceptions in your code, you may handle them in the +following places, in order of priority: + -# In a @c try/catch block inside an event handler. + -# In wxApp::OnExceptionInMainLoop(). + -# In wxApp::OnUnhandledException(). + +In the first two cases you may decide whether you want to handle the exception +and continue execution or to exit the program. In the last one the program is +about to exit already so you can just try to save any unsaved data and notify +the user about the problem (while being careful not to throw any more +exceptions as otherwise @c std::terminate() will be called). @section overview_exceptions_tech Technicalities To use any kind of exception support in the library you need to build it -with @c wxUSE_EXCEPTIONS set to 1. This should be the case by default but -if it isn't, you should edit the @c include/wx/msw/setup.h file under -Windows or run @c configure with @c --enable-exceptions argument -under Unix. +with @c wxUSE_EXCEPTIONS set to 1. It is turned on by default but you may +wish to check @c include/wx/msw/setup.h file under Windows or run @c configure +with explicit @c --enable-exceptions argument under Unix. On the other hand, if you do not plan to use exceptions, setting this flag to 0 or using @c --disable-exceptions could result in a leaner and diff --git a/interface/wx/app.h b/interface/wx/app.h index f0f2e61ade..9e20713bae 100644 --- a/interface/wx/app.h +++ b/interface/wx/app.h @@ -468,15 +468,21 @@ public: virtual int OnRun(); /** - This function is called when an unhandled C++ exception occurs inside - OnRun() (the exceptions which occur during the program startup and shutdown - might not be caught at all). Notice that by now the main event loop has been - terminated and the program will exit, if you want to prevent this from happening - (i.e. continue running after catching an exception) you need to override - OnExceptionInMainLoop(). - - The default implementation shows information about the exception in debug build - but does nothing in the release build. + This function is called when an unhandled C++ exception occurs in user + code called by wxWidgets. + + Any unhandled exceptions thrown from (overridden versions of) OnInit() + and OnExit() methods as well as any exceptions thrown from inside the + main loop and re-thrown by OnUnhandledException() will result in a call + to this function. + + By the time this function is called, the program is already about to + exit and the exception can't be handled nor ignored any more, override + OnUnhandledException() or use explicit @c try/catch blocks around + OnInit() body to be able to handle the exception earlier. + + The default implementation dumps information about the exception using + wxMessageOutputBest. */ virtual void OnUnhandledException(); -- 2.45.2