$darkmode
Qore Programming Language - C/C++ Library 1.19.2
ExceptionSink.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  ExceptionSink.h
4 
5  Qore Programming Language ExceptionSink class definition
6 
7  Copyright (C) 2003 - 2023 Qore Technologies, s.r.o.
8 
9  Permission is hereby granted, free of charge, to any person obtaining a
10  copy of this software and associated documentation files (the "Software"),
11  to deal in the Software without restriction, including without limitation
12  the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  and/or sell copies of the Software, and to permit persons to whom the
14  Software is furnished to do so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in
17  all copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  DEALINGS IN THE SOFTWARE.
26 
27  Note that the Qore library is released under a choice of three open-source
28  licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29  information.
30 */
31 
32 #ifndef _QORE_EXCEPTIONSINK_H
33 
34 #define _QORE_EXCEPTIONSINK_H
35 
36 #include <cstdarg>
37 #include <cstdio>
38 #include <string>
39 #include <vector>
40 
41 // forward references
42 class QoreException;
43 class ExceptionSink;
44 class QoreXSinkException;
45 struct QoreProgramLocation;
46 struct QoreCallStack;
47 class AbstractStatement;
48 
51  friend struct qore_es_private;
52  friend QoreXSinkException;
53 
54 public:
56  DLLEXPORT ExceptionSink();
57 
59  DLLEXPORT ~ExceptionSink();
60 
62  DLLEXPORT void handleExceptions();
63 
65  DLLEXPORT void handleWarnings();
66 
68  DLLEXPORT bool isEvent() const;
69 
71  DLLEXPORT bool isThreadExit() const;
72 
74  DLLEXPORT bool isException() const;
75 
77 
83  DLLEXPORT operator bool () const;
84 
86 
91  DLLEXPORT AbstractQoreNode* raiseException(const char *err, const char *fmt, ...);
92 
94 
100  DLLEXPORT AbstractQoreNode* raiseErrnoException(const char *err, int en, const char *fmt, ...);
101 
103 
109  DLLEXPORT AbstractQoreNode* raiseErrnoException(const char *err, int en, QoreStringNode* desc);
110 
112 
118  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, const char* fmt, ...);
119 
121 
127  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, QoreStringNode* desc);
128 
130 
140  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, QoreStringNode* desc, const QoreCallStack& stack);
141 
143 
154  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreStringNode* desc, const QoreCallStack& stack);
155 
157 
167  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreStringNode* desc);
168 
170 
175  DLLEXPORT AbstractQoreNode* raiseException(const char *err, QoreStringNode* desc);
176 
178 
184 
186 
197 
199 
207  DLLEXPORT void raiseException(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreValue desc);
208 
210 
218  DLLEXPORT void raiseException(const QoreProgramLocation& loc, const char* err, QoreValue arg, const char* fmt, ...);
219 
221  DLLEXPORT void raiseThreadExit();
222 
224  DLLEXPORT void assimilate(ExceptionSink *xs);
225 
227  DLLEXPORT void assimilate(ExceptionSink &xs);
228 
230 
232  DLLEXPORT void outOfMemory();
233 
235  DLLEXPORT void clear();
236 
238  DLLEXPORT const QoreValue getExceptionErr();
239 
241  DLLEXPORT const QoreValue getExceptionDesc();
242 
244  DLLEXPORT const QoreValue getExceptionArg();
245 
247 
251  DLLEXPORT int appendLastDescription(const char* fmt, ...);
252 
253  // Renames the "err" key of the top exception and prepends a string description to any desc value
258  DLLEXPORT int renamePrependLastException(const char* err, const char* desc_fmt, ...);
259 
260  DLLLOCAL void raiseException(QoreException* e);
261  DLLLOCAL void raiseException(const QoreListNode* n);
262  DLLLOCAL QoreException* catchException();
263  DLLLOCAL QoreException* getException();
264  DLLLOCAL void overrideLocation(const QoreProgramLocation& loc);
265  DLLLOCAL void rethrow(QoreException* old);
266 
267  DLLLOCAL static void defaultExceptionHandler(QoreException* e);
268  DLLLOCAL static void defaultWarningHandler(QoreException* e);
269 
270  DLLLOCAL static void outputExceptionLocation(const char* fns, int start_line, int end_line, const char* srcs,
271  int offset, const char* langs, const char* types);
272 
273 private:
275  struct qore_es_private* priv;
276 
277  ExceptionSink(const ExceptionSink&) = delete;
278  ExceptionSink& operator=(const ExceptionSink&) = delete;
279 };
280 
282 enum qore_call_t : signed char {
283  CT_UNUSED = -1,
284  CT_USER = 0,
285  CT_BUILTIN = 1,
286  CT_NEWTHREAD = 2,
287  CT_RETHROW = 3
288 };
289 
291 
294  std::string label;
297  std::string source;
298  unsigned offset = 0;
299  std::string code;
300  std::string lang;
301 
302  DLLLOCAL QoreSourceLocation(const char* label, int start, int end, const char* code, const char* lang = "Qore") :
303  label(label), start_line(start), end_line(end), code(code), lang(lang) {
304  }
305 
306  DLLLOCAL QoreSourceLocation(const char* label, int start, int end, const char* source, unsigned offset,
307  const char* code, const char* lang = "Qore") :
309  }
310 };
311 
313 
316  qore_call_t type;
317 
318  DLLLOCAL QoreCallStackElement(qore_call_t type, const char* label, int start, int end, const char* code,
319  const char* lang = "Qore") :
320  QoreSourceLocation(label, start, end, code, lang), type(type) {
321  }
322 
323  DLLLOCAL QoreCallStackElement(qore_call_t type, const char* label, int start, int end, const char* source,
324  unsigned offset, const char* code, const char* lang = "Qore") :
325  QoreSourceLocation(label, start, end, source, offset, code, lang), type(type) {
326  }
327 };
328 
329 typedef std::vector<QoreCallStackElement> callstack_vec_t;
330 
332 
334 struct QoreCallStack : public callstack_vec_t {
336  DLLEXPORT void add(qore_call_t type, const char* label, int start, int end, const char* code,
337  const char* lang = "Qore");
338 
340  DLLEXPORT void add(qore_call_t type, const char* label, int start, int end, const char* source,
341  unsigned offset, const char* code, const char* lang = "Qore");
342 };
343 
344 static inline void alreadyDeleted(ExceptionSink *xsink, const char *cmeth) {
345  xsink->raiseException("OBJECT-ALREADY-DELETED", "the method %s() cannot be executed because the object has already been deleted", cmeth);
346 }
347 
348 static inline void makeAccessDeletedObjectException(ExceptionSink *xsink, const char *mem, const char *cname) {
349  xsink->raiseException("OBJECT-ALREADY-DELETED", "attempt to access member '%s' of an already-deleted object of class '%s'", mem, cname);
350 }
351 
352 static inline void makeAccessDeletedObjectException(ExceptionSink *xsink, const char *cname) {
353  xsink->raiseException("OBJECT-ALREADY-DELETED", "attempt to access an already-deleted object of class '%s'", cname);
354 }
355 
358 public:
361 
364 
367 
369  DLLEXPORT QoreExternalProgramLocationWrapper(const char* file, int start_line, int end_line,
370  const char* source = nullptr, int offset = 0, const char* lang = nullptr);
371 
374 
376  DLLEXPORT void set(const char* file, int start_line, int end_line,
377  const char* source = nullptr, int offset = 0, const char* lang = nullptr);
378 
380  DLLLOCAL const QoreProgramLocation& get() const {
381  return *loc;
382  }
383 
385  DLLLOCAL const std::string& getFile() const {
386  return file_str;
387  }
388 
390  DLLLOCAL const std::string& getSource() const {
391  return source_str;
392  }
393 
395  DLLLOCAL const std::string& getLanguage() const {
396  return lang_str;
397  }
398 
400  DLLEXPORT int getStartLine() const;
401 
403  DLLEXPORT int getEndLine() const;
404 
405 private:
406  // save strings for exceptions in case they are epheremal when this object is created
407  std::string file_str;
408  std::string source_str;
409  std::string lang_str;
410 
411  // actual exception location
412  QoreProgramLocation* loc;
413 };
414 
416 
419 public:
421  DLLLOCAL QoreStackLocation();
422 
424  DLLLOCAL QoreStackLocation(const QoreStackLocation&) = default;
425 
427  DLLLOCAL QoreStackLocation(QoreStackLocation&&) = default;
428 
430  DLLLOCAL virtual ~QoreStackLocation() = default;
431 
433  DLLLOCAL QoreStackLocation& operator=(const QoreStackLocation&) = default;
434 
437 
439 
446  DLLLOCAL void setNext(const QoreStackLocation* next) {
447  stack_next = next;
448  }
449 
451  DLLLOCAL virtual const QoreStackLocation* getNext() const {
452  return stack_next;
453  }
454 
456  DLLLOCAL virtual QoreProgram* getProgram() const = 0;
457 
459  DLLLOCAL virtual const AbstractStatement* getStatement() const = 0;
460 
462  DLLLOCAL virtual const std::string& getCallName() const = 0;
463 
465  DLLLOCAL virtual qore_call_t getCallType() const = 0;
466 
468  DLLLOCAL virtual const QoreProgramLocation& getLocation() const = 0;
469 
470 protected:
471  const QoreStackLocation* stack_next = nullptr;
472 };
473 
475 
478  friend class qore_external_runtime_stack_location_helper_priv;
479 public:
482 
485 
488 
490  DLLEXPORT virtual ~QoreExternalStackLocation();
491 
494 
497 
499  DLLEXPORT virtual QoreProgram* getProgram() const;
500 
502  DLLEXPORT virtual const AbstractStatement* getStatement() const;
503 
504 private:
505  class qore_external_stack_location_priv* priv;
506 };
507 
509 
512 public:
515 
518 
521 
524 
527 
530 
531 private:
532  class qore_external_runtime_stack_location_helper_priv* priv;
533 };
534 
535 #endif
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:57
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:50
DLLEXPORT void assimilate(ExceptionSink *xs)
assimilates all entries of the "xs" argument by appending them to the internal list and deletes the "...
DLLEXPORT bool isEvent() const
returns true if at least one exception is present or thread_exit has been triggered
DLLEXPORT AbstractQoreNode * raiseErrnoException(const char *err, int en, const char *fmt,...)
appends a Qore-language exception to the list and appends the result of strerror(errno) to the descri...
DLLEXPORT const QoreValue getExceptionErr()
returns the error of the top exception
DLLEXPORT void raiseThreadExit()
sets the "thread_exit" flag; will cause the current thread to terminate
DLLEXPORT const QoreValue getExceptionArg()
returns the argument of the top exception
DLLEXPORT const QoreValue getExceptionDesc()
returns the description of the top exception
DLLEXPORT int appendLastDescription(const char *fmt,...)
appends a formatted string to the top exception description if the desc value is a string
DLLEXPORT AbstractQoreNode * raiseExceptionArg(const char *err, QoreValue arg, const char *fmt,...)
appends a Qore-language exception to the list, and sets the 'arg' member (this object takes over the ...
DLLEXPORT void outOfMemory()
intended to be used to handle out of memory errors
DLLEXPORT int renamePrependLastException(const char *err, const char *desc_fmt,...)
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
DLLEXPORT void handleWarnings()
calls ExceptionSink::defaultWarningHandler() on all exceptions still present in the object and then d...
DLLEXPORT void handleExceptions()
calls ExceptionSink::defaultExceptionHandler() on all exceptions still present in the object and then...
DLLEXPORT void clear()
deletes the exception list immediately
DLLEXPORT ~ExceptionSink()
calls ExceptionSink::defaultExceptionHandler() on all exceptions still present in the object and then...
DLLEXPORT ExceptionSink()
creates an empty ExceptionSink object
DLLEXPORT bool isThreadExit() const
returns true if thread_exit has been triggered
DLLEXPORT bool isException() const
returns true if at least one exception is present
returns a custom Qore program location for external modules to generate runtime exceptions with the s...
Definition: ExceptionSink.h:357
DLLLOCAL const std::string & getLanguage() const
returns the language
Definition: ExceptionSink.h:395
DLLEXPORT int getEndLine() const
returns the start line
DLLLOCAL const QoreProgramLocation & get() const
returns the source location
Definition: ExceptionSink.h:380
DLLEXPORT QoreExternalProgramLocationWrapper()
empty constructor; use set() to set the location
DLLEXPORT void set(const char *file, int start_line, int end_line, const char *source=nullptr, int offset=0, const char *lang=nullptr)
sets the program source location
DLLLOCAL const std::string & getFile() const
returns the file name
Definition: ExceptionSink.h:385
DLLLOCAL const std::string & getSource() const
returns the source
Definition: ExceptionSink.h:390
DLLEXPORT ~QoreExternalProgramLocationWrapper()
destructor; frees memory
DLLEXPORT int getStartLine() const
returns the start line
Sets the stack location for external modules providing language support.
Definition: ExceptionSink.h:511
DLLEXPORT QoreExternalRuntimeStackLocationHelper()
Sets the current runtime location.
DLLEXPORT ~QoreExternalRuntimeStackLocationHelper()
Restores the old runtime location.
DLLLOCAL QoreExternalRuntimeStackLocationHelper & operator=(const QoreExternalRuntimeStackLocationHelper &)=delete
no assignment operator
Stack location element abstract class for external binary modules.
Definition: ExceptionSink.h:477
virtual DLLEXPORT ~QoreExternalStackLocation()
destroys the object
virtual DLLEXPORT QoreProgram * getProgram() const
returns the QoreProgram container
DLLEXPORT QoreExternalStackLocation()
create the object
virtual DLLEXPORT const AbstractStatement * getStatement() const
returns the statement for the call for internal Qore code
DLLLOCAL QoreExternalStackLocation & operator=(const QoreExternalStackLocation &)=delete
no assignment operator
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition: QoreProgram.h:128
Stack location element abstract class.
Definition: ExceptionSink.h:418
virtual DLLLOCAL const QoreProgramLocation & getLocation() const =0
returns the source location of the element
virtual DLLLOCAL const AbstractStatement * getStatement() const =0
returns the statement for the call for internal Qore code
virtual DLLLOCAL const QoreStackLocation * getNext() const
returns the next location in the stack or nullptr if there is none
Definition: ExceptionSink.h:451
virtual DLLLOCAL const std::string & getCallName() const =0
returns the name of the function or method call
DLLLOCAL QoreStackLocation & operator=(const QoreStackLocation &)=default
default assignment operator
virtual DLLLOCAL QoreProgram * getProgram() const =0
returns the QoreProgram container
virtual DLLLOCAL ~QoreStackLocation()=default
virtual destructor
DLLLOCAL void setNext(const QoreStackLocation *next)
called when pushed on the stack to set the next location
Definition: ExceptionSink.h:446
DLLLOCAL QoreStackLocation()
constructor
virtual DLLLOCAL qore_call_t getCallType() const =0
returns the call type
Qore's string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
class for C++ exception based on an ExceptionSink object
Definition: QoreXSinkException.h:51
call stack element; strings must be in the default encoding for the Qore process
Definition: ExceptionSink.h:315
qore_call_t type
the call stack element type
Definition: ExceptionSink.h:316
Qore call stack.
Definition: ExceptionSink.h:334
DLLEXPORT void add(qore_call_t type, const char *label, int start, int end, const char *code, const char *lang="Qore")
add an element to the end of the stack trace
Qore source location; strings must be in the default encoding for the Qore process.
Definition: ExceptionSink.h:293
unsigned offset
offset in source file (only used if source is not empty)
Definition: ExceptionSink.h:298
std::string label
the code label name (source file if source not present)
Definition: ExceptionSink.h:294
int end_line
the end line
Definition: ExceptionSink.h:296
int start_line
the start line
Definition: ExceptionSink.h:295
std::string code
the function or method call name; method calls in format class::name
Definition: ExceptionSink.h:299
std::string source
optional additional source file
Definition: ExceptionSink.h:297
std::string lang
the source language
Definition: ExceptionSink.h:300
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:276