From: Dmitry Volyntsev Date: Wed, 3 Jun 2026 02:07:15 +0000 (-0700) Subject: XML: fixed exception classes X-Git-Tag: 1.0.0~24 X-Git-Url: http://git.kaiwu.me/sitemap.xml?a=commitdiff_plain;h=5ea549cf54ce0de22e2c10b1c470406cb90f4725;p=njs.git XML: fixed exception classes Report XML API misuse as TypeError and XML parse failures as SyntaxError, aligning njs and QuickJS behavior. The QuickJS message "'this' is not XMLNode or XMLDoc" is changed to "value is not XMLNode or XMLDoc" because qjs_xml_node() is not always validating this. --- diff --git a/external/njs_xml_module.c b/external/njs_xml_module.c index f1d275aa..4736c3ac 100644 --- a/external/njs_xml_module.c +++ b/external/njs_xml_module.c @@ -2022,7 +2022,7 @@ njs_xml_error(njs_vm_t *vm, njs_xml_doc_t *current, const char *fmt, ...) err->int2); } - njs_vm_error(vm, "%*s", p - errstr, errstr); + njs_vm_syntax_error(vm, "%*s", p - errstr, errstr); } diff --git a/external/qjs_xml_module.c b/external/qjs_xml_module.c index af297e5b..36dfdba8 100644 --- a/external/qjs_xml_module.c +++ b/external/qjs_xml_module.c @@ -384,7 +384,7 @@ qjs_xml_doc_get_own_property(JSContext *cx, JSPropertyDescriptor *pdesc, tree = JS_GetOpaque(obj, QJS_CORE_CLASS_ID_XML_DOC); if (tree == NULL) { - (void) JS_ThrowInternalError(cx, "\"this\" is not an XMLDoc"); + (void) JS_ThrowTypeError(cx, "\"this\" is not an XMLDoc"); return -1; } @@ -469,7 +469,7 @@ qjs_xml_doc_get_own_property_names(JSContext *cx, JSPropertyEnum **ptab, tree = JS_GetOpaque(obj, QJS_CORE_CLASS_ID_XML_DOC); if (tree == NULL) { - (void) JS_ThrowInternalError(cx, "\"this\" is not an XMLDoc"); + (void) JS_ThrowTypeError(cx, "\"this\" is not an XMLDoc"); return -1; } @@ -741,9 +741,9 @@ qjs_xml_node_tag_modify(JSContext *cx, JSValue obj, njs_str_t *name, } if (!JS_IsNullOrUndefined(setval)) { - JS_ThrowInternalError(cx, "XMLNode.$tag$xxx is not assignable, " - "use addChild() or node.$tags = [node1, node2, ..] " - "syntax"); + JS_ThrowTypeError(cx, "XMLNode.$tag$xxx is not assignable, " + "use addChild() or node.$tags = [node1, node2, ..] " + "syntax"); return -1; } @@ -929,7 +929,7 @@ qjs_xml_node_get_own_property(JSContext *cx, JSPropertyDescriptor *pdesc, current = JS_GetOpaque(obj, QJS_CORE_CLASS_ID_XML_NODE); if (current == NULL) { - (void) JS_ThrowInternalError(cx, "\"this\" is not an XMLNode"); + (void) JS_ThrowTypeError(cx, "\"this\" is not an XMLNode"); return -1; } @@ -1173,7 +1173,7 @@ qjs_xml_node_get_own_property_names(JSContext *cx, JSPropertyEnum **ptab, tree = JS_GetOpaque(obj, QJS_CORE_CLASS_ID_XML_NODE); if (tree == NULL) { - (void) JS_ThrowInternalError(cx, "\"this\" is not an XMLNode"); + (void) JS_ThrowTypeError(cx, "\"this\" is not an XMLNode"); return -1; } @@ -1552,7 +1552,7 @@ qjs_xml_node(JSContext *cx, JSValueConst val, xmlDoc **doc) if (current == NULL) { tree = JS_GetOpaque(val, QJS_CORE_CLASS_ID_XML_DOC); if (tree == NULL) { - JS_ThrowInternalError(cx, "'this' is not XMLNode or XMLDoc"); + JS_ThrowTypeError(cx, "value is not XMLNode or XMLDoc"); return NULL; } @@ -1611,7 +1611,7 @@ qjs_xml_attr_get_own_property(JSContext *cx, JSPropertyDescriptor *pdesc, current = JS_GetOpaque(obj, QJS_CORE_CLASS_ID_XML_ATTR); if (current == NULL) { - (void) JS_ThrowInternalError(cx, "\"this\" is not an XMLAttr"); + (void) JS_ThrowTypeError(cx, "\"this\" is not an XMLAttr"); return -1; } @@ -1675,7 +1675,7 @@ qjs_xml_attr_get_own_property_names(JSContext *cx, JSPropertyEnum **ptab, current = JS_GetOpaque(obj, QJS_CORE_CLASS_ID_XML_ATTR); if (current == NULL) { - (void) JS_ThrowInternalError(cx, "\"this\" is not an XMLAttr"); + (void) JS_ThrowTypeError(cx, "\"this\" is not an XMLAttr"); return -1; } diff --git a/test/xml/xml.t.mjs b/test/xml/xml.t.mjs index 4533c8ad..8590bddc 100644 --- a/test/xml/xml.t.mjs +++ b/test/xml/xml.t.mjs @@ -366,6 +366,18 @@ let modify_tsuite = { return xml.serializeToString(doc); }, expected: `ToveJani` }, + { get: (doc) => { + try { + doc.note.$tag$xxx = doc.note.to; + } catch (e) { + if (e instanceof TypeError) { + return 'OK'; + } + } + + throw Error('unexpected exception'); + }, + expected: 'OK' }, { doc: `ABC`, get: (doc) => { doc.$root.removeChildren('a');