Qore Programming Language  1.9.1
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 - 2022 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 QoreXSinkException;
44 hashdecl QoreProgramLocation;
45 hashdecl QoreCallStack;
46 
49  friend hashdecl qore_es_private;
50  friend QoreXSinkException;
51 
52 public:
54  DLLEXPORT ExceptionSink();
55 
57  DLLEXPORT ~ExceptionSink();
58 
60  DLLEXPORT void handleExceptions();
61 
63  DLLEXPORT void handleWarnings();
64 
66  DLLEXPORT bool isEvent() const;
67 
69  DLLEXPORT bool isThreadExit() const;
70 
72  DLLEXPORT bool isException() const;
73 
75 
81  DLLEXPORT operator bool () const;
82 
84 
89  DLLEXPORT AbstractQoreNode* raiseException(const char *err, const char *fmt, ...);
90 
92 
98  DLLEXPORT AbstractQoreNode* raiseErrnoException(const char *err, int en, const char *fmt, ...);
99 
101 
107  DLLEXPORT AbstractQoreNode* raiseErrnoException(const char *err, int en, QoreStringNode* desc);
108 
110 
116  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, const char* fmt, ...);
117 
119 
125  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, QoreStringNode* desc);
126 
128 
138  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const char* err, QoreValue arg, QoreStringNode* desc, const QoreCallStack& stack);
139 
141 
152  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreStringNode* desc, const QoreCallStack& stack);
153 
155 
165  DLLEXPORT AbstractQoreNode* raiseExceptionArg(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreStringNode* desc);
166 
168 
173  DLLEXPORT AbstractQoreNode* raiseException(const char *err, QoreStringNode* desc);
174 
176 
182 
184 
195 
197 
205  DLLEXPORT void raiseException(const QoreProgramLocation& loc, const char* err, QoreValue arg, QoreValue desc);
206 
208 
216  DLLEXPORT void raiseException(const QoreProgramLocation& loc, const char* err, QoreValue arg, const char* fmt, ...);
217 
219  DLLEXPORT void raiseThreadExit();
220 
222  DLLEXPORT void assimilate(ExceptionSink *xs);
223 
225  DLLEXPORT void assimilate(ExceptionSink &xs);
226 
228 
230  DLLEXPORT void outOfMemory();
231 
233  DLLEXPORT void clear();
234 
236  DLLEXPORT const QoreValue getExceptionErr();
237 
239  DLLEXPORT const QoreValue getExceptionDesc();
240 
242  DLLEXPORT const QoreValue getExceptionArg();
243 
245 
249  DLLEXPORT int appendLastDescription(const char* fmt, ...);
250 
251  DLLLOCAL void raiseException(QoreException* e);
252  DLLLOCAL void raiseException(const QoreListNode* n);
253  DLLLOCAL QoreException* catchException();
254  DLLLOCAL QoreException* getException();
255  DLLLOCAL void overrideLocation(const QoreProgramLocation& loc);
256  DLLLOCAL void rethrow(QoreException* old);
257 
258  DLLLOCAL static void defaultExceptionHandler(QoreException* e);
259  DLLLOCAL static void defaultWarningHandler(QoreException* e);
260 
261  DLLLOCAL static void outputExceptionLocation(const char* fns, int start_line, int end_line, const char* srcs,
262  int offset, const char* langs, const char* types);
263 
264 private:
266  hashdecl qore_es_private* priv;
267 
268  ExceptionSink(const ExceptionSink&) = delete;
269  ExceptionSink& operator=(const ExceptionSink&) = delete;
270 };
271 
273 enum qore_call_t : signed char {
274  CT_UNUSED = -1,
275  CT_USER = 0,
276  CT_BUILTIN = 1,
277  CT_NEWTHREAD = 2,
278  CT_RETHROW = 3
279 };
280 
282 
285  std::string label;
288  std::string source;
289  unsigned offset = 0;
290  std::string code;
291  std::string lang;
292 
293  DLLLOCAL QoreSourceLocation(const char* label, int start, int end, const char* code, const char* lang = "Qore") :
294  label(label), start_line(start), end_line(end), code(code), lang(lang) {
295  }
296 
297  DLLLOCAL QoreSourceLocation(const char* label, int start, int end, const char* source, unsigned offset,
298  const char* code, const char* lang = "Qore") :
300  }
301 };
302 
304 
307  qore_call_t type;
308 
309  DLLLOCAL QoreCallStackElement(qore_call_t type, const char* label, int start, int end, const char* code,
310  const char* lang = "Qore") :
311  QoreSourceLocation(label, start, end, code, lang), type(type) {
312  }
313 
314  DLLLOCAL QoreCallStackElement(qore_call_t type, const char* label, int start, int end, const char* source,
315  unsigned offset, const char* code, const char* lang = "Qore") :
316  QoreSourceLocation(label, start, end, source, offset, code, lang), type(type) {
317  }
318 };
319 
320 typedef std::vector<QoreCallStackElement> callstack_vec_t;
321 
323 
325 hashdecl QoreCallStack : public callstack_vec_t {
327  DLLEXPORT void add(qore_call_t type, const char* label, int start, int end, const char* code,
328  const char* lang = "Qore");
329 
331  DLLEXPORT void add(qore_call_t type, const char* label, int start, int end, const char* source,
332  unsigned offset, const char* code, const char* lang = "Qore");
333 };
334 
335 static inline void alreadyDeleted(ExceptionSink *xsink, const char *cmeth) {
336  xsink->raiseException("OBJECT-ALREADY-DELETED", "the method %s() cannot be executed because the object has already been deleted", cmeth);
337 }
338 
339 static inline void makeAccessDeletedObjectException(ExceptionSink *xsink, const char *mem, const char *cname) {
340  xsink->raiseException("OBJECT-ALREADY-DELETED", "attempt to access member '%s' of an already-deleted object of class '%s'", mem, cname);
341 }
342 
343 static inline void makeAccessDeletedObjectException(ExceptionSink *xsink, const char *cname) {
344  xsink->raiseException("OBJECT-ALREADY-DELETED", "attempt to access an already-deleted object of class '%s'", cname);
345 }
346 
349 public:
352 
355 
358 
360  DLLEXPORT QoreExternalProgramLocationWrapper(const char* file, int start_line, int end_line,
361  const char* source = nullptr, int offset = 0, const char* lang = nullptr);
362 
365 
367  DLLEXPORT void set(const char* file, int start_line, int end_line,
368  const char* source = nullptr, int offset = 0, const char* lang = nullptr);
369 
371  DLLLOCAL const QoreProgramLocation& get() const {
372  return *loc;
373  }
374 
376  DLLLOCAL const std::string& getFile() const {
377  return file_str;
378  }
379 
381  DLLLOCAL const std::string& getSource() const {
382  return source_str;
383  }
384 
386  DLLLOCAL const std::string& getLanguage() const {
387  return lang_str;
388  }
389 
391  DLLEXPORT int getStartLine() const;
392 
394  DLLEXPORT int getEndLine() const;
395 
396 private:
397  // save strings for exceptions in case they are epheremal when this object is created
398  std::string file_str;
399  std::string source_str;
400  std::string lang_str;
401 
402  // actual exception location
403  QoreProgramLocation* loc;
404 };
405 
407 
410 public:
412  DLLLOCAL QoreStackLocation();
413 
415  DLLLOCAL QoreStackLocation(const QoreStackLocation&) = default;
416 
418  DLLLOCAL QoreStackLocation(QoreStackLocation&&) = default;
419 
421  DLLLOCAL virtual ~QoreStackLocation() = default;
422 
424  DLLLOCAL QoreStackLocation& operator=(const QoreStackLocation&) = default;
425 
428 
430 
437  DLLLOCAL void setNext(const QoreStackLocation* next) {
438  stack_next = next;
439  }
440 
442  DLLLOCAL virtual const QoreStackLocation* getNext() const {
443  return stack_next;
444  }
445 
447  DLLLOCAL virtual QoreProgram* getProgram() const = 0;
448 
450  DLLLOCAL virtual const AbstractStatement* getStatement() const = 0;
451 
453  DLLLOCAL virtual const std::string& getCallName() const = 0;
454 
456  DLLLOCAL virtual qore_call_t getCallType() const = 0;
457 
459  DLLLOCAL virtual const QoreProgramLocation& getLocation() const = 0;
460 
461 protected:
462  const QoreStackLocation* stack_next = nullptr;
463 };
464 
466 
469  friend class qore_external_runtime_stack_location_helper_priv;
470 public:
473 
476 
479 
481  DLLEXPORT virtual ~QoreExternalStackLocation();
482 
485 
488 
490  DLLEXPORT virtual QoreProgram* getProgram() const;
491 
493  DLLEXPORT virtual const AbstractStatement* getStatement() const;
494 
495 private:
496  class qore_external_stack_location_priv* priv;
497 };
498 
500 
503 public:
506 
509 
512 
515 
518 
521 
522 private:
523  class qore_external_runtime_stack_location_helper_priv* priv;
524 };
525 
526 #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:48
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 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:348
DLLLOCAL const std::string & getLanguage() const
returns the language
Definition: ExceptionSink.h:386
DLLEXPORT int getEndLine() const
returns the start line
DLLLOCAL const QoreProgramLocation & get() const
returns the source location
Definition: ExceptionSink.h:371
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:376
DLLLOCAL const std::string & getSource() const
returns the source
Definition: ExceptionSink.h:381
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:502
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:468
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:127
Stack location element abstract class.
Definition: ExceptionSink.h:409
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:442
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:437
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:306
qore_call_t type
the call stack element type
Definition: ExceptionSink.h:307
Qore call stack.
Definition: ExceptionSink.h:325
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:284
unsigned offset
offset in source file (only used if source is not empty)
Definition: ExceptionSink.h:289
std::string label
the code label name (source file if source not present)
Definition: ExceptionSink.h:285
int end_line
the end line
Definition: ExceptionSink.h:287
int start_line
the start line
Definition: ExceptionSink.h:286
std::string code
the function or method call name; method calls in format class::name
Definition: ExceptionSink.h:290
std::string source
optional additional source file
Definition: ExceptionSink.h:288
std::string lang
the source language
Definition: ExceptionSink.h:291
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:275