Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Exceptions.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. 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<>{msg, }
100 , fBasedOnException{basedOnException}
101 {
102 }
103
104 /*
105 ********************************************************************************
106 ***************************** SystemErrorException *****************************
107 ********************************************************************************
108 */
109 template <typename BASE_EXCEPTION>
110 inline SystemErrorException<BASE_EXCEPTION>::SystemErrorException (error_code errCode)
111 : SystemErrorException{errCode, Private_::SystemErrorExceptionPrivate_::mkMsg_ (errCode)}
112 {
113 }
114 template <typename BASE_EXCEPTION>
115 inline SystemErrorException<BASE_EXCEPTION>::SystemErrorException (error_code errCode, const Characters::String& message)
116 : inherited{Private_::SystemErrorExceptionPrivate_::mkCombinedMsg_ (errCode, message), errCode}
117 {
118 }
119 template <typename BASE_EXCEPTION>
120 inline SystemErrorException<BASE_EXCEPTION>::SystemErrorException (int ev, const std::error_category& ecat)
121 : SystemErrorException{error_code{ev, ecat}}
122 {
123 }
124 template <typename BASE_EXCEPTION>
125 inline SystemErrorException<BASE_EXCEPTION>::SystemErrorException (int ev, const std::error_category& ecat, const Characters::String& message)
126 : SystemErrorException{error_code{ev, ecat}, message}
127 {
128 }
129 template <typename BASE_EXCEPTION>
130 template <typename... BASE_EXCEPTION_ARGS>
131 inline SystemErrorException<BASE_EXCEPTION>::SystemErrorException (const Characters::String& reasonForError, BASE_EXCEPTION_ARGS... baseExceptionArgs)
132 : inherited{reasonForError, forward<BASE_EXCEPTION_ARGS> (baseExceptionArgs)...}
133 {
134 }
135
136 /*
137 ********************************************************************************
138 ******************************** ThrowPOSIXErrNo *******************************
139 ********************************************************************************
140 */
141 inline void ThrowPOSIXErrNo (errno_t errNo)
142 {
143#if Stroia_Foundation_Execution_Exceptions_USE_NOISY_TRACE_IN_THIS_MODULE_
144 TraceContenxtBumper tctx{"Execution::ThrowPOSIXErrNo", "{}"_f, errNo};
145#endif
146 Require (errNo != 0);
147#if qStroika_Foundation_Common_Platform_POSIX
148 error_code ec{errNo, system_category ()};
149#else
150 error_code ec{errNo, generic_category ()};
151#endif
152 Private_::SystemErrorExceptionPrivate_::TranslateException_ (ec);
154 }
155
156 /*
157 ********************************************************************************
158 ************************* ThrowPOSIXErrNoIfNegative ****************************
159 ********************************************************************************
160 */
161 template <typename INT_TYPE>
162 inline INT_TYPE ThrowPOSIXErrNoIfNegative (INT_TYPE returnCode)
163 {
164 if (returnCode < 0) [[unlikely]] {
165 ThrowPOSIXErrNo (errno);
166 }
167 return returnCode;
168 }
169
170 /*
171 ********************************************************************************
172 ******************************** ThrowSystemErrNo ******************************
173 ********************************************************************************
174 */
175 inline void ThrowSystemErrNo (int sysErr)
176 {
177#if Stroia_Foundation_Execution_Exceptions_USE_NOISY_TRACE_IN_THIS_MODULE_
178 TraceContenxtBumper tctx{"Execution::ThrowSystemErrNo", "{}"_f, sysErr};
179#endif
180 Require (sysErr != 0);
181 error_code ec{sysErr, system_category ()};
182 Private_::SystemErrorExceptionPrivate_::TranslateException_ (ec);
183 Throw (SystemErrorException{ec});
185#if qStroika_Foundation_Common_Platform_POSIX or qStroika_Foundation_Common_Platform_Windows
186 [[noreturn]] inline void ThrowSystemErrNo ()
187 {
188#if qStroika_Foundation_Common_Platform_POSIX
189 ThrowSystemErrNo (errno);
190#elif qStroika_Foundation_Common_Platform_Windows
191 ThrowSystemErrNo (::GetLastError ());
192#endif
193 }
194#endif
195
196 /*
197 ********************************************************************************
198 ************************ Handle_ErrNoResultInterruption ************************
199 ********************************************************************************
200 */
201 template <typename CALL>
202 auto Handle_ErrNoResultInterruption (CALL call) -> decltype (call ())
203 {
204 decltype (call ()) ret; // intentionally uninitialized since always set at least once before read
205 do {
206 ret = call ();
208 } while (ret < 0 and errno == EINTR);
209 return ThrowPOSIXErrNoIfNegative (ret);
210 }
211
212 /*
213 ********************************************************************************
214 ****************************** ThrowPOSIXErrNoIfNull ***************************
215 ********************************************************************************
216 */
217 inline void ThrowPOSIXErrNoIfNull (void* returnValue)
218 {
219 if (returnValue == nullptr) [[unlikely]] {
220 ThrowPOSIXErrNo (errno);
221 }
222 }
223
224 /*
225 ********************************************************************************
226 ************************** TranslateExceptionToOptional ************************
227 ********************************************************************************
228 */
229 template <typename F>
230 inline auto TranslateExceptionToOptional (F&& f) -> optional<remove_cvref_t<invoke_result_t<F>>>
231 {
232 try {
233 return f ();
234 }
235 catch (...) {
236 //using namespace Characters::Literals;
237 //DbgTrace ("Mapping exception in TranslateExceptionToOptional to nullopt: {}"_f, current_exception ());
238 return nullopt;
239 }
240 }
241
242}
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:1049
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)