Testing Dynamic Errors - xspec/xspec GitHub Wiki
With <x:scenario catch="yes">
, its descendant-or-self scenarios will catch dynamic errors when invoking the tested module. The standard error variables including $err:code
and $err:description
are collected in $x:result?err
as a map. For example, $x:result?err?code
stores $err:code
. If the tested module didn't throw an error, $x:result
contains its return items intact as usual.
For Schematron, @catch
will work just like XSLT, although it won't make sense.
@catch
is a rather new feature and its details are subject to change. Any feedback is welcome.
Stylesheet:
<xsl:template name="my-template-with-error">
<xsl:sequence
select="error(
xs:QName('error-code-of-my-template'),
'error description of my template',
('error', 'object', 'of', 'my', 'template')
)" />
</xsl:template>
XSpec:
<x:description ...>
<x:scenario catch="yes" label="Testing an error">
<x:call template="my-template-with-error" />
<x:expect label="err:code" test="$x:result?err?code"
select="xs:QName('error-code-of-my-template')" />
<x:expect label="err:description" test="$x:result?err?description"
select="'error description of my template'" />
<x:expect label="err:value" test="$x:result?err?value treat as xs:string+"
select="'error', 'object', 'of', 'my', 'template'" />
</x:scenario>
</x:scenario>
@catch="yes"
catches <xsl:message terminate="yes">
in the same way as the other dynamic errors. In this case, however, your error message body is not in $x:result?err?description
but in $x:result?err?value
, and it is not an exact copy of your error message body but a document node containing your error message body.
Stylesheet:
<xsl:template name="my-template-with-simple-termination">
<xsl:message select="'my error message'" terminate="yes" />
</xsl:template>
XSpec:
<x:scenario catch="yes" label="Testing a termination with a simple message">
<x:call template="my-template-with-simple-termination" />
<x:expect label="err:code" select="QName('http://www.w3.org/2005/xqt-errors', 'XTMM9000')"
test="$x:result?err?code" />
<x:expect label="err:value" test="$x:result?err?value/text()">my error message</x:expect>
</x:scenario>
In version 10 and earlier, Saxon inserts a <?error-code?>
processing instruction into the error message document. Expect it at the head of child nodes, if you test the error message document as a whole.
Stylesheet:
<xsl:template name="my-template-with-complex-termination">
<xsl:message terminate="yes">
<my-error-element-1>foo</my-error-element-1>
<xsl:comment>my error comment</xsl:comment>
<my-error-element-2>bar</my-error-element-2>
</xsl:message>
</xsl:template>
XSpec:
<x:scenario catch="yes" label="Testing a termination with a complex message">
<x:call template="my-template-with-complex-termination" />
<x:expect label="err:value" select="/" test="$x:result?err?value treat as document-node()">
<?error-code Q{http://www.w3.org/2005/xqt-errors}XTMM9000?>
<my-error-element-1>foo</my-error-element-1>
<!--my error comment-->
<my-error-element-2>bar</my-error-element-2>
</x:expect>
</x:scenario>
Note that Saxon 10.1 or older has a bug that may prevent you from testing $x:result?err?value
with <xsl:message terminate="yes">
.