32 #ifndef _QORE_QOREEXCEPTION_H
34 #define _QORE_QOREEXCEPTION_H
39 hashdecl QoreExceptionBase {
45 qore_call_t n_type = CT_BUILTIN);
47 DLLLOCAL QoreExceptionBase(
const QoreExceptionBase& old) :
48 type(old.type), callStack(old.callStack->copy()),
49 err(old.err.refSelf()), desc(old.desc.refSelf()),
50 arg(old.arg.refSelf()) {
53 DLLLOCAL ~QoreExceptionBase() {
58 hashdecl QoreExceptionLocation : QoreProgramLineLocation {
64 DLLLOCAL QoreExceptionLocation() {
67 DLLLOCAL QoreExceptionLocation(
const QoreProgramLocation& loc) : QoreProgramLineLocation(loc),
68 file(loc.getFileValue()), source(loc.getSourceValue()), lang(loc.getLanguageValue()), offset(loc.offset) {
71 DLLLOCAL QoreExceptionLocation(
const QoreExceptionLocation& old) : QoreProgramLineLocation(old),
72 file(old.file), source(old.source), lang(old.lang), offset(old.offset) {
75 DLLLOCAL QoreExceptionLocation(QoreExceptionLocation&& old) =
default;
77 DLLLOCAL QoreExceptionLocation& operator=(
const QoreExceptionLocation& other) {
78 start_line = other.start_line;
79 end_line = other.end_line;
81 source = other.source;
83 offset = other.offset;
87 DLLLOCAL
void set(
const QoreProgramLocation& loc) {
88 start_line = loc.start_line;
89 end_line = loc.end_line;
90 file = loc.getFileValue();
91 source = loc.getSourceValue();
92 lang = loc.getLanguageValue();
96 DLLLOCAL
bool isBuiltin()
const {
97 return file ==
"<builtin>" && (start_line == end_line) && (start_line == -1);
101 class QoreException :
public QoreExceptionBase,
public QoreExceptionLocation {
103 friend hashdecl qore_es_private;
106 QoreException* next =
nullptr;
110 DLLLOCAL
QoreHashNode* makeExceptionObject(
int level = 0)
const;
115 QoreExceptionLocation(*get_runtime_location()) {
119 : QoreExceptionBase(n_err, n_desc, n_arg),
120 QoreExceptionLocation(*get_runtime_location()) {
123 DLLLOCAL QoreException(
const QoreException& old) : QoreExceptionBase(old),
124 QoreExceptionLocation(old), next(old.next ? new QoreException(*old.next) : nullptr) {
128 DLLLOCAL QoreException(
const QoreListNode* n) : QoreExceptionBase(0, 0, 0, CT_USER),
129 QoreExceptionLocation(*get_runtime_location()) {
137 DLLLOCAL QoreException(
const QoreProgramLocation& n_loc,
const char *n_err,
QoreValue n_desc,
139 QoreExceptionBase(new
QoreStringNode(n_err), n_desc, n_arg, n_type), QoreExceptionLocation(n_loc) {
142 DLLLOCAL
void getLocation(QoreExceptionLocation& loc)
const {
143 if (isBuiltin() && callStack) {
147 assert(v.getType() ==
NT_HASH);
151 if (*str !=
"<builtin>") {
152 loc.file = str->
c_str();
153 kv = v.get<
const QoreHashNode>()->getKeyValue(
"source");
162 loc.start_line = kv.getAsBigInt();
163 kv = v.get<
const QoreHashNode>()->getKeyValue(
"endline");
164 loc.end_line = kv.getAsBigInt();
165 kv = v.get<
const QoreHashNode>()->getKeyValue(
"offset");
166 loc.offset = kv.getAsBigInt();
177 DLLLOCAL QoreException* rethrow();
180 DLLLOCAL ~QoreException() {
189 DLLLOCAL
static const char* getType(qore_call_t type);
194 DLLLOCAL QoreException& operator=(
const QoreException&) =
delete;
197 class ParseException :
public QoreException {
200 DLLLOCAL ParseException(
const QoreProgramLocation& loc,
const char* err,
QoreStringNode* desc) : QoreException(loc, err, desc) {
204 hashdecl qore_es_private {
205 bool thread_exit =
false;
206 QoreException* head =
nullptr, * tail =
nullptr;
208 DLLLOCAL qore_es_private() {
211 DLLLOCAL ~qore_es_private() {
214 DLLLOCAL
void clearIntern() {
219 head = tail =
nullptr;
223 DLLLOCAL
void insert(QoreException *e) {
232 DLLLOCAL
void appendListIntern(
QoreString& str)
const {
233 QoreException* w = head;
239 if (!w->file.empty())
240 str.
sprintf(
"%s:", w->file.c_str());
242 str.
sprintf(
"%d", w->start_line);
243 if (w->end_line && w->end_line != w->start_line)
244 str.
sprintf(
"-%d", w->end_line);
247 str.
sprintf(
"%s: %s", err->getBuffer(), desc->getBuffer());
256 DLLLOCAL
void addStackInfo(qore_call_t type,
const char *class_name,
const char *code,
257 const QoreProgramLocation& loc);
264 QoreException* w = head;
274 for (
auto& i : stack)
278 DLLLOCAL
void assimilate(qore_es_private& es);
280 DLLLOCAL
static void addStackInfo(
ExceptionSink& xsink, qore_call_t type,
const char* class_name,
281 const char* code,
const QoreProgramLocation& loc) {
282 xsink.priv->addStackInfo(type, class_name, code, loc);
286 xsink.priv->appendListIntern(str);
290 class ParseExceptionSink {
295 DLLLOCAL ~ParseExceptionSink();