Audacity 3.2.0
AudacityException.h
Go to the documentation of this file.
1#ifndef __AUDACITY_EXCEPTION__
2#define __AUDACITY_EXCEPTION__
3
4/*!********************************************************************
5
6 Audacity: A Digital Audio Editor
7
8 @file AudacityException.h
9 @brief Declare abstract class AudacityException, some often-used subclasses, and @ref GuardedCall
10
11 Paul Licameli
12 **********************************************************************/
13
14#include "MemoryX.h"
15#include <exception>
16#include <functional>
17
18#include "Internat.h"
19
21enum class ExceptionType
22{
23 Internal,
26};
27
29
32class EXCEPTIONS_API AudacityException /* not final */
33{
34public:
36 virtual ~AudacityException() = 0;
37
39 virtual void DelayedHandlerAction() = 0;
40
41 static void EnqueueAction(
42 std::exception_ptr pException,
43 std::function<void(AudacityException*)> delayedHandler);
44
45protected:
48
50 // see https://bugzilla.audacityteam.org/show_bug.cgi?id=2442
52
54 AudacityException &operator = ( const AudacityException & ) = delete;
55};
56
58
60class EXCEPTIONS_API MessageBoxException /* not final */
61 : public AudacityException
62{
65
67 void DelayedHandlerAction() final;
68
69protected:
71 explicit MessageBoxException(
72 ExceptionType exceptionType,
73 const TranslatableString &caption
74 );
75 ~MessageBoxException() override;
76
78
80 virtual TranslatableString ErrorMessage() const = 0;
81 virtual wxString ErrorHelpUrl() const { return helpUrl; };
82
83private:
86
87 mutable bool moved { false };
88protected:
89 mutable wxString helpUrl{ "" };
90};
91
93class EXCEPTIONS_API SimpleMessageBoxException /* not final */
94 : public MessageBoxException
95{
96public:
98 ExceptionType exceptionType,
99 const TranslatableString &message_, //<! Message to show
100 const TranslatableString &caption = XO("Message"), //<! Short caption in frame around message
101 const wxString &helpUrl_ = "" // Optional URL for help.
102 )
103 : MessageBoxException { exceptionType, caption }
104 , message{ message_ }
105 {
106 helpUrl = helpUrl_;
107 }
109
112 SimpleMessageBoxException && ) = delete;
113
114 // Format a default, internationalized error message for this exception.
115 virtual TranslatableString ErrorMessage() const override;
116
117private:
119};
120
121
124{
125 if ( pException )
126 pException->DelayedHandlerAction();
127}
128
130
131template <typename R> struct SimpleGuard
132{
133 explicit SimpleGuard(
134 const R &value
135 )
136 noexcept(noexcept( R{ std::declval<const R&>() } ))
137 : m_value{ value } {}
139 noexcept(noexcept( R{ std::declval<R>() } ))
140 { return m_value; }
141 const R m_value;
142};
143
145template<> struct SimpleGuard<bool>
146{
147 explicit SimpleGuard(
148 bool value
149 ) noexcept
150 : m_value{ value } {}
151 bool operator () ( AudacityException * ) const noexcept { return m_value; }
152 static SimpleGuard Default() noexcept
153 { return SimpleGuard{ false }; }
154 const bool m_value;
155};
156
158template<> struct SimpleGuard<void>
159{
160 SimpleGuard() noexcept {}
161 void operator () ( AudacityException * ) const noexcept {}
162 static SimpleGuard Default() noexcept { return {}; }
163};
164
166template < typename R >
168 noexcept(noexcept( SimpleGuard< R >{ value } ))
169 { return SimpleGuard< R >{ value }; }
170
172inline SimpleGuard< void > MakeSimpleGuard() noexcept { return {}; }
173
196template <
197 typename R = void,
198
199 typename F1, // function object with signature R()
200
201 typename F2 = SimpleGuard< R >, // function object
202 // with signature R( AudacityException * )
203
204 typename F3 = void (*)(AudacityException *pException)
205>
208 const F1 &body,
209 const F2 &handler = F2::Default(),
210 F3 delayedHandler = DefaultDelayedHandlerAction
212)
213noexcept(
214 noexcept( handler( std::declval<AudacityException*>() ) ) &&
215 noexcept( handler( nullptr ) ) &&
216 noexcept(
217 std::function<void(AudacityException*)>{std::move(delayedHandler)} ) )
218{
219 try { return body(); }
220 catch ( AudacityException &e ) {
221 #ifndef UNCAUGHT_EXCEPTIONS_UNAVAILABLE
222 const auto uncaughtExceptionsCount = std::uncaught_exceptions();
223 #endif
224 auto end = finally( [&]()
225 noexcept(noexcept(
226 std::function<void(AudacityException*)>{
227 std::move(delayedHandler)} )) {
228 // At this point, e is the "current" exception, but not "uncaught"
229 // unless it was rethrown by handler. handler might also throw some
230 // other exception object.
231 #ifdef UNCAUGHT_EXCEPTIONS_UNAVAILABLE
232 if (!std::uncaught_exception()) {
233 #else
234 if (uncaughtExceptionsCount >= std::uncaught_exceptions()) {
235 #endif
236 auto pException = std::current_exception(); // This points to e
238 pException, std::move(delayedHandler));
239 }
240 });
241
242 return handler( &e );
243 }
244 catch ( ... ) {
245 return handler( nullptr );
246 }
247}
248
249#endif
ExceptionType
A type of an exception.
@ BadEnvironment
Indicates problems with environment, such as a full disk.
@ BadUserAction
Indicates that the user performed an action that is not allowed.
@ Internal
Indicates internal failure from Audacity.
SimpleGuard< R > MakeSimpleGuard(R value) noexcept(noexcept(SimpleGuard< R >{ value }))
Convert a value to a handler function returning that value, suitable for GuardedCall<R>
void DefaultDelayedHandlerAction(AudacityException *pException)
A default template parameter for GuardedCall.
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), F3 delayedHandler=DefaultDelayedHandlerAction) noexcept(noexcept(handler(std::declval< AudacityException * >())) &&noexcept(handler(nullptr)) &&noexcept(std::function< void(AudacityException *)>{std::move(delayedHandler)}))
Execute some code on any thread; catch any AudacityException; enqueue error report on the main thread...
XO("Cut/Copy/Paste")
Base class for exceptions specially processed by the application.
virtual void DelayedHandlerAction()=0
Action to do in the main thread at idle time of the event loop.
static void EnqueueAction(std::exception_ptr pException, std::function< void(AudacityException *)> delayedHandler)
AudacityException(AudacityException &&)=delete
Don't allow moves of this class or subclasses.
AudacityException(const AudacityException &)=default
Make this protected to prevent slicing copies.
Abstract AudacityException subclass displays a message, specified by further subclass.
virtual TranslatableString ErrorMessage() const =0
Format the error message for this exception.
virtual wxString ErrorHelpUrl() const
TranslatableString caption
Stored caption.
ExceptionType exceptionType
Exception type.
A MessageBoxException that shows a given, unvarying string.
SimpleMessageBoxException(const SimpleMessageBoxException &)=default
TranslatableString message
Stored message.
SimpleMessageBoxException(ExceptionType exceptionType, const TranslatableString &message_, const TranslatableString &caption=XO("Message"), const wxString &helpUrl_="")
Holds a msgid for the translation catalog; may also bind format arguments.
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
static SimpleGuard Default() noexcept
SimpleGuard(bool value) noexcept
Specialization of SimpleGuard, also defining a default value.
static SimpleGuard Default() noexcept
A default template parameter for GuardedCall<R>
SimpleGuard(const R &value) noexcept(noexcept(R{ std::declval< const R & >() }))
R operator()(AudacityException *) const noexcept(noexcept(R{ std::declval< R >() }))