This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 28955 - [XSLT30] xsl:try should probably include xs:error in its enumeration
Summary: [XSLT30] xsl:try should probably include xs:error in its enumeration
Status: CLOSED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Last Call drafts
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-07-16 08:14 UTC by Abel Braaksma
Modified: 2015-10-29 12:42 UTC (History)
0 users

See Also:


Attachments

Description Abel Braaksma 2015-07-16 08:14:54 UTC
In XP31 we now have xs:error. The first numbered list item enumerates conditions that raise a catchable exception. The peculiar nature of xs:error warrants inclusion, I think.

I assume it will normally behave like a type error, but I'm not sure it will follow the same semantics entirely.

Example:

<xsl:try>
   <xsl:variable name="err" select="xs:error()" />
   <xsl:value-of select="if(foo) then $err else bar" />
   <xsl:catch>
       <xsl:text>Problem, foo found!</xsl:text>
   </xsl:catch>
</xsl:try>
Comment 1 Abel Braaksma 2015-08-20 17:23:14 UTC
This bug applies to section 8.3 on Try/Catch, the text:

<quote>
1. All dynamic errors occurring during the evaluation of the xsl:try sequence constructor or select expression are caught (provided they match one of the xsl:catch elements).

 * This includes errors occurring in functions or templates invoked in the course of this evaluation, unless already caught by a nested xsl:try.

 * It also includes errors caused by calling the error function, or the xsl:message instruction with terminate="yes", or the xsl:assert instruction.

 * It does not include errors that occur while evaluating references to variables whose declaration and initialization is outside the xsl:try.
</quote>

The text seems to try to be complete, which is why I raised this bug. We could (should?) include that _using_ a variable that is declared as xs:error, and/or set to the value xs:error(), when used (not when declared) will raise an exception that _can_ be caught by the try/catch.
Comment 2 Michael Kay 2015-08-21 08:15:25 UTC
The first sentence tries to be comprehensive "All dynamic errors occurring during the evaluation.. are caught". There is little room for doubt about what constitutes a dynamic error, but there is room for debate about what "during the evaluation" means. The further paragraphs attempt to explain some cases where an error is considered to occur "during the evaluation", and others where it does not occur "during the evaluation".

I think the text makes it clear that when an error occurs evaluating the initialising expression of a variable, the error is "during" the xsl:try if the variable declaration is within the xsl:try, and not otherwise.

I think we also make it clear that type errors can be detected statically (in which case they aren't caught), or dynamically (in which case they are).

I can't really see that xs:error() is different in this respect from other type errors, e.g. xs:date(23), or that it merits special rules.
Comment 3 Abel Braaksma 2015-08-21 09:38:22 UTC
Ok, I thought the bullets were trying to enumerate all situations that could throw an error, but if that is just a list of examples to the text before it, there's nothing that needs to be done.

But it still raises questions:

In XP31 we say:
> A variable binding with a type declaration xs:error always raises a type error.

But this is confusing. I think from an XSLT point of view, it is not the binding that will raise an error. Instead, it is the reference.

This sentence suggests that the following always throws, but I think that is incorrect:

<xsl:sequence select="
   let $t := xs:error()  (: variable binding, but should not raise, right? :)
   return if(foo eq '')  (: safe still :)
   then $t               (: raises error "if and only if" :)
   else foo              (: safe, no error :) " />

Also, perhaps we should even be less strict about the leniency with global variables. We say that if a variable contains a type error, it *may* be raised pro-actively, but may also be raised upon usage. Considering the current text, if anybody has the following, it *may* always raise an error and prevent the stylesheet from being processed in the first place:

<!-- global -->
<xsl:variable 
   name="err" 
   select="xs:error('err:ERR001', 'Handy placeholder for throwing errors')" 
   as="xs:error" />


But then again, making one exception on a type xs:error to prohibit early evaluation does not sound like the best idea either. But what would a user expect?
Comment 4 Abel Braaksma 2015-08-23 09:49:07 UTC
> select="xs:error('err:ERR001', 'Handy placeholder for throwing errors')" 

This should have been fn:error, of course...

But that results in no type (none), which, while contradictory, is a fait accompli of XP30, so it really should've been xs:error('Handy placeholder for throwing errors'), to illustrate the use-case.
Comment 5 Michael Kay 2015-08-26 21:49:51 UTC
There are two points here.

Firstly, xs:error() and fn:error() aren't any different from other type errors and dynamic errors, except perhaps that they are deliberate rather than accidental.

Secondly, errors occurring during the binding of a variable are within the scope of a try/catch if and only if the variable declaration is within the xsl:try. I think we make this clear, but if you think otherwise, I'm prepared to try harder...

The XPath statement "A variable binding with a type declaration xs:error always raises a type error." is perhaps unfortunate. It always raises a type error if it is evaluated (or if the processor does static typing). I don't think it is helpful to state that it is the variable reference that causes the error. Yes, a common optimization is to evaluate variables lazily, and in this case the evaluation of a variable reference will in some sense trigger the error, but if the variable binding is outside the try/catch and the variable reference is inside it, the try/catch will have no effect, for the simple reason that lazy evaluation is only an optimization.
Comment 6 Michael Kay 2015-09-12 21:47:01 UTC
The text has been clarified as follows, to emphasize that all dynamic errors are caught and the list only includes selected examples:

All dynamic errors occurring during the evaluation of the xsl:try sequence constructor or select expression are caught (provided they match one of the xsl:catch elements). 

<note>
 * This includes errors occurring in functions or templates invoked in
 the course of this evaluation, unless already caught by a nested
 xsl:try.

  * It also includes (for
    example) errors caused by calling the error function, or the xsl:message   terminate="yes", or the xsl:assert instruction, or the xs:error constructor
function.

  * It does not include errors that occur while evaluating references to
    variables whose declaration and initialization is outside the
    xsl:try.

</note>