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
This commit is contained in:
@@ -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
|
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.
|
could result in memory and/or resource leaks, and also not very convenient.
|
||||||
|
|
||||||
wxWidgets is exception-friendly.
|
However the recent wxWidgets versions are exception-friendly. This means that
|
||||||
It still doesn't use the exceptions by itself but it should be now safe to use the
|
while the library still doesn't use the exceptions by itself, it should be now
|
||||||
exceptions in the user code and the library tries to help you with this. Please
|
safe to use the exceptions in the user code and the library tries to help you
|
||||||
note that making the library exception-safe is still work in progress.
|
with this.
|
||||||
|
|
||||||
|
|
||||||
@section overview_exceptions_strategies Strategies for exceptions handling
|
@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
|
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.
|
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
|
The next simplest strategy is to only use exceptions inside non-GUI code, i.e.
|
||||||
this case you probably don't expect to recover from them and the default
|
never let unhandled exceptions escape the event handler in which it happened.
|
||||||
behaviour -- to simply terminate the program -- may be appropriate. If it is
|
In this case using exceptions in wxWidgets programs is not different from using
|
||||||
not, you may override wxApp::OnUnhandledException()
|
them in any other C++ program.
|
||||||
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
|
Things get more interesting if you decide to let (at least some) exceptions
|
||||||
occur. If all of your exceptions may happen only in the event handlers of a
|
escape from the event handler in which they occurred. Such exceptions will be
|
||||||
single class (or only in the classes derived from it), you may centralize your
|
caught by wxWidgets and the special wxApp::OnExceptionInMainLoop() method will
|
||||||
exception handling code in wxApp::ProcessEvent
|
be called from the @c catch clause. This allows you to decide in a single place
|
||||||
method of this class. If this is impractical, you may also consider overriding
|
what to do about such exceptions: you may want to handle the exception somehow
|
||||||
the wxApp::HandleEvent() which allows you to handle
|
or terminate the program. In this sense, OnExceptionInMainLoop() is equivalent
|
||||||
all the exceptions thrown by any event handler.
|
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
|
@section overview_exceptions_tech Technicalities
|
||||||
|
|
||||||
To use any kind of exception support in the library you need to build it
|
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
|
with @c wxUSE_EXCEPTIONS set to 1. It is turned on by default but you may
|
||||||
if it isn't, you should edit the @c include/wx/msw/setup.h file under
|
wish to check @c include/wx/msw/setup.h file under Windows or run @c configure
|
||||||
Windows or run @c configure with @c --enable-exceptions argument
|
with explicit @c --enable-exceptions argument under Unix.
|
||||||
under Unix.
|
|
||||||
|
|
||||||
On the other hand, if you do not plan to use exceptions, setting this
|
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
|
flag to 0 or using @c --disable-exceptions could result in a leaner and
|
||||||
|
@@ -468,15 +468,21 @@ public:
|
|||||||
virtual int OnRun();
|
virtual int OnRun();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function is called when an unhandled C++ exception occurs inside
|
This function is called when an unhandled C++ exception occurs in user
|
||||||
OnRun() (the exceptions which occur during the program startup and shutdown
|
code called by wxWidgets.
|
||||||
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
|
Any unhandled exceptions thrown from (overridden versions of) OnInit()
|
||||||
but does nothing in the release build.
|
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();
|
virtual void OnUnhandledException();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user