How Do xsl:try and xsl:catch Work in XSLT 3.0?

Error handling in modern XSLT workflows relies on the <xsl:try> and <xsl:catch> instructions introduced in XSLT 3.0 to intercept dynamic runtime failures without halting stylesheet execution. This article examines how these elements operate, how to filter specific error codes, how to access diagnostic error variables, and how to implement graceful fallbacks for fragile data transformations.

The Need for Robust Error Handling in XSLT

Prior to XSLT 3.0, dynamic errors—such as division by zero, invalid data type casting, or missing external documents—invariably caused the transformation engine to abort the entire process. Stylesheet authors often had to write complex defensive logic using conditional statements or rely on proprietary extension functions to check data validity before evaluation.

The introduction of <xsl:try> and <xsl:catch> brings structured exception handling to declarative XML processing, allowing stylesheets to attempt potentially volatile operations, recover from expected edge cases, and continue producing output.

Core Syntax and Mechanics

The <xsl:try> element encloses the sequence constructor that might throw a dynamic error. If the evaluation completes successfully, the resulting sequence is delivered to the output. If an error occurs within the <xsl:try> block, execution immediately halts, the partial results of that block are discarded, and control transfers to the matching <xsl:catch> branch.

<xsl:try>
    <!-- Attempt a risky transformation -->
    <xsl:value-of select="xs:decimal(price) * xs:integer(quantity)" />
    <xsl:catch>
        <!-- Provide fallback content -->
        <span class="error">Invalid numeric data</span>
    </xsl:catch>
</xsl:try>

An <xsl:try> element must contain at least one <xsl:catch> block. Multiple <xsl:catch> elements can be declared sequentially to handle different failure modes with tailored responses.

Filtering Errors with the errors Attribute

By default, an unqualified <xsl:catch> block catches any dynamic error. When finer control is required, the errors attribute specifies a list of NameTests matching error QNames:

<xsl:try>
    <xsl:value-of select="unparsed-text(@href)" />
    <xsl:catch errors="err:FOUT1170">
        <xsl:text>Resource not found at target URI.</xsl:text>
    </xsl:catch>
    <xsl:catch errors="err:FOUT1190">
        <xsl:text>Resource encoding cannot be decoded.</xsl:text>
    </xsl:catch>
    <xsl:catch errors="*">
        <xsl:text>An unexpected dynamic error occurred.</xsl:text>
    </xsl:catch>
</xsl:try>

The processor checks <xsl:catch> blocks in the order they appear and executes the first one matching the raised error code.

Standard Error Variables

Within the scope of an <xsl:catch> block, XSLT 3.0 provides several implicitly declared variables in the standard error namespace ([http://www.w3.org/2005/xqt-errors](http://www.w3.org/2005/xqt-errors), typically bound to prefix err):

These variables allow detailed logging or contextual error reporting:

<xsl:catch>
    <error-log code="{$err:code}" line="{$err:line-number}">
        <xsl:value-of select="$err:description" />
    </error-log>
</xsl:catch>

Common Applications

Structured error handling is particularly valuable in modern data pipelines that handle external or loosely structured inputs:

  1. Parsing External Resources: Safeguarding calls to fn:doc(), fn:unparsed-text(), or fn:json-doc() against network latency, missing files, or corrupt payloads.
  2. Dynamic JSON Parsing: Intercepting syntax errors when converting raw strings using fn:parse-json().
  3. Data Type Casting: Converting legacy string formats into strict XML Schema types (xs:dateTime, xs:decimal) without crashing when non-conformant input is encountered.
  4. Regular Expression Evaluation: Catching invalid dynamic regex patterns compiled at runtime via fn:matches() or fn:tokenize().

By wrapping volatile operations in <xsl:try> and supplying defensive strategies in <xsl:catch>, stylesheets maintain operational resilience across unpredictable input sources.