static const QoreStringNode* get_string_header_node(ExceptionSink* xsink, QoreHashNode& h, const char* header, bool allow_multiple = false) { AbstractQoreNode* n = h.getKeyValue(header); if (!n) return 0; qore_type_t t = get_node_type(n); if (t == NT_STRING) return reinterpret_cast<const QoreStringNode*>(n); assert(t == NT_LIST); if (!allow_multiple) { xsink->raiseException("HTTP-HEADER-ERROR", "multiple \"%s\" headers received in HTTP message", header); return 0; } // convert list to a comma-separated string QoreListNode* l = reinterpret_cast<QoreListNode*>(n); // get first list entry n = l->retrieve_entry(0); assert(get_node_type(n) == NT_STRING); QoreStringNode* rv = reinterpret_cast<QoreStringNode*>(n)->copy(); for (size_t i = 1; i < l->size(); ++i) { n = l->retrieve_entry(i); assert(get_node_type(n) == NT_STRING); rv->concat(','); rv->concat(reinterpret_cast<QoreStringNode*>(n)); } // dereference old list and save reference to return value in header hash h.setKeyValue(header, rv, xsink); return rv; }
ExpressionStatement::ExpressionStatement(int start_line, int end_line, AbstractQoreNode *v) : AbstractStatement(start_line, end_line), exp(v) { // if it is a global variable declaration, then do not register if (exp->getType() == NT_VARREF) { VarRefNode *vr = reinterpret_cast<VarRefNode *>(exp); // used by QoreProgram to detect invalid top-level statements is_declaration = !vr->has_effect(); // used in parsing to eliminate noops from the parse tree is_parse_declaration = !vr->stayInTree(); return; } QoreListNode *l = exp->getType() == NT_LIST ? reinterpret_cast<QoreListNode *>(exp) : 0; if (l && l->isVariableList()) { is_declaration = true; is_parse_declaration = reinterpret_cast<VarRefNode *>(l->retrieve_entry(0))->getType() == VT_GLOBAL ? true : false; return; } is_declaration = false; is_parse_declaration = false; }
// static member function void ExceptionSink::defaultExceptionHandler(QoreException* e) { ExceptionSink xsink; QoreString nstr; { DateTime now; now.setNow(); now.format(nstr, "YYYY-MM-DD HH:mm:SS.xx Dy Z (z)"); } unsigned ecnt = 0; while (e) { //printd(5, "ExceptionSink::defaultExceptionHandler() cs size=%d\n", cs->size()); printe("unhandled QORE %s exception thrown in TID %d at %s", e->type == ET_USER ? "User" : "System", gettid(), nstr.getBuffer()); QoreListNode *cs = e->callStack; bool found = false; if (cs->size()) { // find first non-rethrow element unsigned i = 0; QoreHashNode *h; while (true) { h = reinterpret_cast<QoreHashNode *>(cs->retrieve_entry(i)); assert(h); if ((reinterpret_cast<QoreBigIntNode *>(h->getKeyValue("typecode")))->val != CT_RETHROW) break; i++; if (i == cs->size()) break; } if (i < cs->size()) { found = true; QoreStringNode *func = reinterpret_cast<QoreStringNode *>(h->getKeyValue("function")); QoreStringNode *type = reinterpret_cast<QoreStringNode *>(h->getKeyValue("type")); printe(" in %s() (%s:%d", func->getBuffer(), e->file.c_str(), e->start_line); if (e->start_line == e->end_line) { if (!e->source.empty()) printe(", source %s:%d", e->source.c_str(), e->start_line + e->offset); } else { printe("-%d", e->end_line); if (!e->source.empty()) printe(", source %s:%d-%d", e->source.c_str(), e->start_line + e->offset, e->end_line + e->offset); } printe(", %s code)\n", type->getBuffer()); } } if (!found) { if (!e->file.empty()) { printe(" at %s:", e->file.c_str()); if (e->start_line == e->end_line) { if (!e->start_line) { printe("<init>"); if (!e->source.empty()) printe(" (source %s)", e->source.c_str()); } else { printe("%d", e->start_line); if (!e->source.empty()) printe(" (source %s:%d)", e->source.c_str(), e->start_line + e->offset); } } else { printe("%d-%d", e->start_line, e->end_line); if (!e->source.empty()) printe(" (source %s:%d-%d)", e->source.c_str(), e->start_line + e->offset, e->end_line + e->offset); } } else if (e->start_line) { if (e->start_line == e->end_line) { if (!e->start_line) printe(" at <init>"); else printe(" on line %d", e->start_line); } else printe(" on lines %d through %d", e->start_line, e->end_line); } printe("\n"); } if (e->type == ET_SYSTEM) { QoreStringNode* err = reinterpret_cast<QoreStringNode *>(e->err); QoreStringNode* desc = reinterpret_cast<QoreStringNode *>(e->desc); printe("%s: %s\n", err->getBuffer(), desc->getBuffer()); } else { bool hdr = false; if (e->err) { if (e->err->getType() == NT_STRING) { QoreStringNode *err = reinterpret_cast<QoreStringNode *>(e->err); printe("%s", err->getBuffer()); } else { QoreNodeAsStringHelper str(e->err, FMT_NORMAL, &xsink); printe("EXCEPTION: %s", str->getBuffer()); hdr = true; } } else printe("EXCEPTION"); if (e->desc) { if (e->desc->getType() == NT_STRING) { QoreStringNode *desc = reinterpret_cast<QoreStringNode *>(e->desc); printe("%s%s", hdr ? ", desc: " : ": ", desc->getBuffer()); } else { QoreNodeAsStringHelper str(e->desc, FMT_NORMAL, &xsink); printe(", desc: %s", str->getBuffer()); hdr = true; } } if (e->arg) { if (e->arg->getType() == NT_STRING) { QoreStringNode *arg = reinterpret_cast<QoreStringNode *>(e->arg); printe("%s%s", hdr ? ", arg: " : "", arg->getBuffer()); } else { QoreNodeAsStringHelper str (e->arg, FMT_NORMAL, &xsink); printe(", arg: %s", str->getBuffer()); } } printe("\n"); } if (cs->size()) { printe("call stack:\n"); for (unsigned i = 0; i < cs->size(); i++) { int pos = cs->size() - i; QoreHashNode* h = reinterpret_cast<QoreHashNode*>(cs->retrieve_entry(i)); QoreStringNode* strtype = reinterpret_cast<QoreStringNode*>(h->getKeyValue("type")); const char* type = strtype->getBuffer(); int typecode = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("typecode"))->val; if (!strcmp(type, "new-thread")) printe(" %2d: *thread start*\n", pos); else { QoreStringNode* fn = reinterpret_cast<QoreStringNode*>(h->getKeyValue("file")); const char* fns = fn && !fn->empty() ? fn->getBuffer() : 0; int start_line = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("line"))->val; int end_line = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("endline"))->val; QoreStringNode* src = reinterpret_cast<QoreStringNode*>(h->getKeyValue("source")); const char* srcs = src && !src->empty() ? src->getBuffer() : 0; int offset = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("offset"))->val; printe(" %2d: ", pos); if (typecode == CT_RETHROW) { printe("RETHROW at "); if (fn) { printe("%s:", fn->getBuffer()); } else printe("line"); printe("%d", start_line); if (srcs) printe(" (source %s:%d)", srcs, offset + start_line); } else { QoreStringNode* fs = reinterpret_cast<QoreStringNode *>(h->getKeyValue("function")); printe("%s() (", fs->getBuffer()); if (fns) { if (start_line == end_line) { if (!start_line) printe("%s:<init>", fns); else { printe("%s:%d", fns, start_line); if (srcs) printe(" (source %s:%d)", srcs, start_line + offset); } } else { printe("%s:%d-%d", fns, start_line, end_line); if (srcs) printe(" (source %s:%d-%d)", srcs, start_line + offset, end_line + offset); } } else { if (start_line == end_line) { if (!start_line) printe("<init>"); else printe("line %d", start_line); } else printe("line %d - %d", start_line, end_line); } printe(", %s code)", type); } printe("\n"); } } } e = e->next; if (e) { ++ecnt; if (ecnt == Q_MAX_EXCEPTIONS) { printe("*** maximum exception count reached (%d); supressing further output\n", ecnt); break; } printe("chained exception:\n"); } } }