Zum Hauptinhalt springen

Debugging & Troubleshooting

Troubleshooting iXML is faster when you follow a strict reduction workflow: isolate, reproduce, inspect, and fix. This page provides systematic processes for parser errors, runtime exceptions, and data-shape bugs, along with the full debug namespace for development-time inspection.

Debugging Workflow

  1. Reproduce the issue with a minimal snippet using zeysdk run --ixml.
  2. Capture the exact error message and location.
  3. Reduce by removing branches and variables until the root cause is obvious.
  4. Fix the minimal case, then rebuild toward the full version.
  5. Verify the fix works in the original context.

Parser Errors

Parser errors occur before execution. The iXML engine validates XML structure, element names, and attribute names during parsing. Note that error messages show attribute and element names in uppercase — iXML itself is case-insensitive.

Unknown Attribute

Text
ERROR: iXML\ParserException: Unknown attribute "CONDITION" in element "IF"

Cause: Using an attribute that does not exist on the element.

Common cases:

  • <if condition="..."> — Use value1, value2, func instead.
  • <set var="$name"> — Remove the $; it is substitution syntax, not part of variable names.
  • <encode:base64 type="mime">type attribute does not exist on encode:base64.

Fix: Check the command's attribute list in the documentation.

Malformed XML

Text
ERROR: iXML\ParserException: expected '>'

Cause: Invalid XML syntax — unescaped characters in attributes, missing closing tags, or mismatched elements.

Common cases:

  • func="<" — Must be func="&lt;" (XML requires escaping < and > in attribute values).
  • Missing closing tag or mismatched nesting.

Unknown Element

Text
ERROR: iXML\ParserException: Unknown element "DB:ISNOT"

Cause: Using a command that does not exist.

Common cases:

  • <db:isnot> — Does not exist. Use <db:is func="!="> or <db:isnotnull/>.
  • <encode:hex> — Does not exist in the encode namespace.
  • <encode:hmac> — Does not exist. Use <encode:hash algorithm="sha256" key="secret">.
  • <array:count> — Does not exist. Use <size var="count">$array</size>.

Runtime Errors

Runtime errors occur during execution. They can be caught with <try>/<catch>.

Type Errors

Symptom: Unexpected behavior or empty output.

Diagnosis:

XML
<set var="test">42</set>
<typeof var="test" var_result="t"/>
<output>Type: $t</output>
<!-- Output: Type: string -->

Fix: Use <cast> for explicit type conversion:

XML
<cast var="test" type="int"/>
<typeof var="test" var_result="t"/>
<output>Type: $t</output>
<!-- Output: Type: int -->
tip

Common mistake: <set> always creates strings. <set var="x">42</set> creates the string "42", not the integer 42. Use <cast var="x" type="int"/> after setting if you need a numeric type.

Data Shape Inspection

When output is unexpected, serialize intermediate structures to see their actual shape:

XML
<encode:json var="payload" var_result="debug" pretty="1"/>
<output>$debug</output>

Use this before database writes and before final API output to verify the data structure.

Database Errors

Common issues:

  • Type mismatch: contacts.type is smallint, not a string. Using <db:is field="c.type">Customer</db:is> causes a PostgreSQL type error.
  • NULL comparison: <db:is field="c.email">NULL</db:is> does not check for NULL. SQL NULL requires IS NULL syntax — use <db:isnull field="c.email"/>.
  • Access forbidden: System tables like information_schema.columns are blocked in ZeyOS.

Defensive Error Handling

Wrap risky operations in <try>/<catch>:

XML
<try>
<decode:json var="data">$body</decode:json>
<catch var="err">
<set var="return">400</set>
<output>Invalid JSON: $err</output>
</catch>
</try>

Debug Commands

The debug namespace provides four commands for development-time inspection. See ZeyOS Platform Services for full documentation.

debug:output

Full reference →

Writes a message to the debug console (separate from application output — you will not see it in zeysdk run --ixml results):

XML
<debug:output>Processing ID: $id, Status: $status</debug:output>

debug:dump

Full reference →

Dumps all variables or a specific variable with recursive structure inspection:

XML
<!-- Dump a specific variable -->
<debug:dump var="contacts"/>

<!-- Dump all variables -->
<debug:dump/>

debug:log

Full reference →

Writes to the debug log file (persisted, unlike console output):

XML
<debug:log>Error processing contact $id: $error_msg</debug:log>

debug:exclude

Full reference →

Temporarily disables a code block without removing it. Unlike XML comments, the code inside is still parsed and validated — so syntax errors in disabled code will still be caught:

XML
<debug:exclude>
<db:delete entity="contacts">
<db:is field="c.status">inactive</db:is>
</db:delete>
</debug:exclude>

Debugging Strategies

Service Endpoint Debugging

When debugging API handlers, check in this order:

  1. Route and method — Is the correct service being invoked?
  2. Body decode — Is the request body valid and parsed correctly?
  3. Validation — Are required fields present and correctly typed?
  4. Database operations — Are queries returning expected results?

This order prevents misdiagnosing downstream failures caused by upstream issues.

Iterative Reduction

When facing a complex bug, reduce the code iteratively:

XML
<!-- Step 1: Does the basic structure work? -->
<output>Step 1: Start</output>

<!-- Step 2: Does the data load correctly? -->
<db:select var="data" entity="contacts" type="self" limit="1">
<db:fields>c.ID, c.name</db:fields>
</db:select>
<encode:json var="data" var_result="json" pretty="1"/>
<output>$json</output>

<!-- Step 3: Add processing logic back one piece at a time -->

Regression Prevention

After fixing a bug:

  1. Keep a minimal reproducer snippet.
  2. Run it again and capture the passing output.
  3. Document the issue to avoid repeating the same mistake.