{"record":{"id":"61ccf1ca76d886c9","repo":"iflytek/astron-agent","slug":"40002-xml-parsing-failed","errorCode":"-40002","errorMessage":"XML parsing failed","messagePattern":"XML parsing failed","errorType":"error_code","errorClass":"AesException","httpStatus":null,"severity":"error","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/util/wechat/XMLParse.java","lineNumber":53,"sourceCode":"            dbf.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n            dbf.setFeature(\"http://apache.org/xml/features/nonvalidating/load-external-dtd\", false);\n            dbf.setXIncludeAware(false);\n            dbf.setExpandEntityReferences(false);\n            DocumentBuilder db = dbf.newDocumentBuilder();\n            StringReader sr = new StringReader(xmltext);\n            InputSource is = new InputSource(sr);\n            Document document = db.parse(is);\n            Element root = document.getDocumentElement();\n            for (String key : keys) {\n                NodeList nodeList = root.getElementsByTagName(key);\n                if (nodeList.getLength() > 0) {\n                    result.put(key, nodeList.item(0).getTextContent());\n                }\n            }\n            return result;\n        } catch (Exception e) {\n            e.printStackTrace();\n            throw new AesException(AesException.ParseXmlError);\n        }\n    }\n\n    /**\n     * Generate XML message\n     *\n     * @param encrypt Encrypted message ciphertext\n     * @param signature Security signature\n     * @param timestamp Timestamp\n     * @param nonce Random string\n     * @return Generated XML string\n     */\n    public static String generate(String encrypt, String signature, String timestamp, String nonce) {\n        String format = \"<xml>%n\" + \"<Encrypt><![CDATA[%1$s]]></Encrypt>%n\"\n                + \"<MsgSignature><![CDATA[%2$s]]></MsgSignature>%n\"\n                + \"<TimeStamp>%3$s</TimeStamp>%n\" + \"<Nonce><![CDATA[%4$s]]></Nonce>%n\" + \"</xml>\";\n        return String.format(format, encrypt, signature, timestamp, nonce);\n    }","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/hub/src/main/java/com/iflytek/astron/console/hub/util/wechat/XMLParse.java#L35-L71","documentation":"XMLParse.extract parses the WeChat callback XML document and pulls out the requested fields (e.g. Encrypt). Any exception during DocumentBuilderFactory parsing or node extraction throws AesException -40002 (ParseXmlError) after a stack-trace print. decryptMsg depends on this to locate the Encrypt element, so a parse failure blocks signature verification and decryption.","triggerScenarios":"Calling extract(xml, fieldNames) with XML that the DocumentBuilder cannot parse: empty or blank string, malformed tags, invalid XML characters, wrong encoding, or a body that is not XML at all.","commonSituations":"Empty POST bodies from health checks or scanners hitting the WeChat callback URL; charset/encoding mismatches; XML containing entities or DOCTYPEs the parser disallows; bodies mangled by middleware before reaching decryptMsg.","solutions":["Log the raw XML body and the printed stack trace to see the exact parse failure.","Reject empty/non-XML bodies with HTTP 400 before calling decryptMsg/extract.","Ensure the body is decoded as UTF-8 and not truncated or re-encoded by proxies or filters.","Sanitize the XML of invalid control characters before parsing if senders may include them."],"exampleFix":"// before\nObject[] encrypt = XMLParse.extract(postData, new String[]{\"Encrypt\"}).values().toArray(); // postData may be blank\n// after\nif (postData == null || postData.isBlank()) {\n    throw new IllegalArgumentException(\"empty callback body\");\n}\nObject[] encrypt = XMLParse.extract(postData, new String[]{\"Encrypt\"}).values().toArray();","handlingStrategy":"try-catch","validationCode":"if (xml == null || xml.isBlank()) throw new IllegalArgumentException(\"empty xml\");","typeGuard":null,"tryCatchPattern":"try { Object[] enc = XMLParse.extract(xml, new String[]{\"Encrypt\"}).values().toArray(); } catch (AesException e) { if (e.getCode() == -40002) { log.warn(\"XML parse error for callback body\"); return \"\"; } throw e; }","preventionTips":["Guard for empty bodies before parsing","Sanitize invalid control characters from inbound XML","Log raw body plus stack trace when diagnosing","Ensure charset is UTF-8 end to end"],"tags":["wechat","xml-parsing","dom","aesexception"],"backgroundTag":"xml-parse-error","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}