Stroika Library 3.0d24
 
Loading...
Searching...
No Matches
Exceptions.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4
5// Comment this in to turn on aggressive noisy DbgTrace in this module
6//#define Stroia_Foundation_Execution_Exceptions_USE_NOISY_TRACE_IN_THIS_MODULE_ 1
7
9
10 namespace Private_::SystemErrorExceptionPrivate_ {
11 Characters::String mkMsg_ (error_code errCode);
12 Characters::String mkCombinedMsg_ (error_code errCode, const Characters::String& message);
13 void TranslateException_ (error_code errCode);
14 unique_ptr<exception> TranslateExceptionQuietly_ (error_code errCode);
15 }
16
17 // forward declare for use below....to avoid #include of Thread.h
18 namespace Thread {
20 }
21
22 /*
23 ********************************************************************************
24 ******************************** ExceptionStringHelper *************************
25 ********************************************************************************
26 */
27 inline ExceptionStringHelper::ExceptionStringHelper (const Characters::String& reasonForError)
28 : ExceptionStringHelper{reasonForError, CaptureCurrentActivities ()}
29 {
30 }
31 inline Characters::String ExceptionStringHelper::GetBasicErrorMessage () const
32 {
33 return fRawErrorMessage_;
34 }
35 inline Characters::String ExceptionStringHelper::GetFullErrorMessage () const
36 {
37 return fFullErrorMessage_;
38 }
39 inline Containers::Stack<Activity<>> ExceptionStringHelper::GetActivities () const
40 {
41 return fActivities_;
42 }
43 template <>
44 inline wstring ExceptionStringHelper::As () const
45 {
46 return fFullErrorMessage_.As<wstring> ();
47 }
48 template <>
49 inline Characters::String ExceptionStringHelper::As () const
50 {
51 return fFullErrorMessage_;
52 }
53 inline const char* ExceptionStringHelper::_PeekAtNarrowSDKString_ () const
54 {
55 return fSDKCharString_.c_str ();
56 }
57
58 /*
59 ********************************************************************************
60 ********************************** Exception ***********************************
61 ********************************************************************************
62 */
63 template <typename BASE_EXCEPTION>
64 inline Exception<BASE_EXCEPTION>::Exception (const Characters::String& reasonForError)
65 : ExceptionStringHelper{reasonForError}
66 , inherited{}
67 {
68 }
69 template <typename BASE_EXCEPTION>
70 template <typename... BASE_EXCEPTION_ARGS>
71 inline Exception<BASE_EXCEPTION>::Exception (const Characters::String& reasonForError, BASE_EXCEPTION_ARGS... baseExceptionArgs)
72 : ExceptionStringHelper{reasonForError}
73 , inherited{forward<BASE_EXCEPTION_ARGS> (baseExceptionArgs)...}
74 {
75 }
76 template <typename BASE_EXCEPTION>
77 const char* Exception<BASE_EXCEPTION>::what () const noexcept
78 {
79 return _PeekAtNarrowSDKString_ ();
80 }
81
82 /*
83 ********************************************************************************
84 **************************** RuntimeErrorException *****************************
85 ********************************************************************************
86 */
87 template <typename BASE_EXCEPTION>
89 : Exception<BASE_EXCEPTION>{msg, ""}
90 {
91 }
92
93 /*
94 ********************************************************************************
95 ******************************* NestedException ********************************
96 ********************************************************************************
97 */
98 inline NestedException::NestedException (const Characters::String& msg, const exception_ptr& basedOnException)
99 : RuntimeErrorException<>{
100 msg,
101 }
102 , fBasedOnException{basedOnException}
103 {
104 }
105
106 /*
107 ********************************************************************************
108 ***************************** SystemErrorException *****************************
109 ********************************************************************************
110 */
111 template <typename BASE_EXCEPTION>
112 inline SystemErrorException<BASE_EXCEPTION>::SystemErrorException (error_code errCode)
113 : SystemErrorException{errCode, Private_::SystemErrorExceptionPrivate_::mkMsg_ (errCode)}
114 {
115 }
116 template <typename BASE_EXCEPTION>
117 inline SystemErrorException<BASE_EXCEPTION>::SystemErrorException (error_code errCode, const Characters::String& message)
118 : inherited{Private_::SystemErrorExceptionPrivate_::mkCombinedMsg_ (errCode, message), errCode}
119 {
120 }
121 template <typename BASE_EXCEPTION>
122 inline SystemErrorException<BASE_EXCEPTION>::SystemErrorException (int ev, const std::error_category& ecat)
123 : SystemErrorException{error_code{ev, ecat}}
124 {
125 }
126 template <typename BASE_EXCEPTION>
127 inline SystemErrorException<BASE_EXCEPTION>::SystemErrorException (int ev, const std::error_category& ecat, const Characters::String& message)
128 : SystemErrorException{error_code{ev, ecat}, message}
129 {
130 }
131 template <typename BASE_EXCEPTION>
132 template <typename... BASE_EXCEPTION_ARGS>
133 inline SystemErrorException<BASE_EXCEPTION>::SystemErrorException (const Characters::String& reasonForError, BASE_EXCEPTION_ARGS... baseExceptionArgs)
134 : inherited{reasonForError, forward<BASE_EXCEPTION_ARGS> (baseExceptionArgs)...}
135 {
136 }
137
138 /*
139 ********************************************************************************
140 ******************************** ThrowPOSIXErrNo *******************************
141 ********************************************************************************
142 */
143 inline void ThrowPOSIXErrNo (errno_t errNo)
144 {
145#if Stroia_Foundation_Execution_Exceptions_USE_NOISY_TRACE_IN_THIS_MODULE_
146 TraceContenxtBumper tctx{"Execution::ThrowPOSIXErrNo", "{}"_f, errNo};
147#endif
148 Require (errNo != 0);
149#if qStroika_Foundation_Common_Platform_POSIX
150 error_code ec{errNo, system_category ()};
151#else
152 error_code ec{errNo, generic_category ()};
153#endif
154 Private_::SystemErrorExceptionPrivate_::TranslateException_ (ec);
156 }
157
158 /*
159 ********************************************************************************
160 ************************* ThrowPOSIXErrNoIfNegative ****************************
161 ********************************************************************************
162 */
163 template <typename INT_TYPE>
164 inline INT_TYPE ThrowPOSIXErrNoIfNegative (INT_TYPE returnCode)
165 {
166 if (returnCode < 0) [[unlikely]] {
167 ThrowPOSIXErrNo (errno);
168 }
169 return returnCode;
170 }
171
172 /*
173 ********************************************************************************
174 ******************************** ThrowSystemErrNo ******************************
175 ********************************************************************************
176 */
177 inline void ThrowSystemErrNo (int sysErr)
178 {
179#if Stroia_Foundation_Execution_Exceptions_USE_NOISY_TRACE_IN_THIS_MODULE_
180 TraceContenxtBumper tctx{"Execution::ThrowSystemErrNo", "{}"_f, sysErr};
181#endif
182 Require (sysErr != 0);
183 error_code ec{sysErr, system_category ()};
184 Private_::SystemErrorExceptionPrivate_::TranslateException_ (ec);
186 }
187#if qStroika_Foundation_Common_Platform_POSIX or qStroika_Foundation_Common_Platform_Windows
188 [[noreturn]] inline void ThrowSystemErrNo ()
189 {
190#if qStroika_Foundation_Common_Platform_POSIX
191 ThrowSystemErrNo (errno);
192#elif qStroika_Foundation_Common_Platform_Windows
193 ThrowSystemErrNo (::GetLastError ());
194#endif
195 }
196#endif
197
198 /*
199 ********************************************************************************
200 ************************ Handle_ErrNoResultInterruption ************************
201 ********************************************************************************
202 */
203 template <typename CALL>
204 auto Handle_ErrNoResultInterruption (CALL call) -> decltype (call ())
205 {
206 decltype (call ()) ret; // intentionally uninitialized since always set at least once before read
207 do {
208 ret = call ();
210 } while (ret < 0 and errno == EINTR);
211 return ThrowPOSIXErrNoIfNegative (ret);
212 }
213
214 /*
215 ********************************************************************************
216 ****************************** ThrowPOSIXErrNoIfNull ***************************
217 ********************************************************************************
218 */
219 inline void ThrowPOSIXErrNoIfNull (void* returnValue)
220 {
221 if (returnValue == nullptr) [[unlikely]] {
222 ThrowPOSIXErrNo (errno);
223 }
224 }
225
226 /*
227 ********************************************************************************
228 ************************** TranslateExceptionToOptional ************************
229 ********************************************************************************
230 */
231 template <typename F>
232 inline auto TranslateExceptionToOptional (F&& f) -> optional<remove_cvref_t<invoke_result_t<F>>>
233 {
234 try {
235 return f ();
236 }
237 catch (...) {
238 //using namespace Characters::Literals;
239 //DbgTrace ("Mapping exception in TranslateExceptionToOptional to nullopt: {}"_f, current_exception ());
240 return nullopt;
241 }
242 }
243
244}
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
nonvirtual tuple< const wchar_t *, wstring_view > c_str(Memory::StackBuffer< wchar_t > *possibleBackingStore) const
Definition String.inl:1057
Exception<> is a replacement (subclass) for any std c++ exception class (e.g. the default 'std::excep...
Definition Exceptions.h:157
virtual const char * what() const noexcept override
nonvirtual CONTAINER_OF_T As(CONTAINER_OF_T_CONSTRUCTOR_ARGS... args) const
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
Definition Throw.inl:43
void ThrowPOSIXErrNo(errno_t errNo=errno)
treats errNo as a POSIX errno value, and throws a SystemError (subclass of @std::system_error) except...
auto Handle_ErrNoResultInterruption(CALL call) -> decltype(call())
Handle UNIX EINTR system call behavior - fairly transparently - just effectively removes them from th...
void ThrowPOSIXErrNoIfNull(void *returnValue)
auto TranslateExceptionToOptional(F &&f) -> optional< remove_cvref_t< invoke_result_t< F > > >
Containers::Stack< Activity<> > CaptureCurrentActivities()
Returns a copyable preservable version of the current activities stack.
Definition Activity.cpp:19
INT_TYPE ThrowPOSIXErrNoIfNegative(INT_TYPE returnCode)