Try-Catch

Try-Catch Grammar

TryCatchExpr ::= TryClause CatchClause+
TryClause ::= "try" "{" TargetExpr "}"
CatchClause ::= "catch" "(" NameTest ( "," ErrorCode ( "," ErrorDescr ( "," ErrorVal)?)? )? ")" "{" Expr "}"
ErrorCode ::= "$" VarName
ErrorDescr ::= "$" VarName
ErrorVal ::= "$" VarName

Try-Catch Examples

A try-catch expression catches errors in expressions that are lexically contained within the try-clause. If the target expression does not raise an error, the result of the try-catch expression is the result of the target expression. If the target expression raises an error, the result of the try-catch expression is obtained by evaluating the first first catch clause that "matches" the error value, as described below. An error matches a catch clause if the error's error code matches the clause's NameTest as defined in XQuery 1.0 (see http://www.w3.org/TR/xquery/#node-tests). If an error is matched, the optional variables in the catch clause are bound, in order, to the error's code, description, and value. These variables are then in scope in the catch clause. If no catch clause matches an error, the error is not caught, and propogates upward. If an error is raised in a catch clause, the error is not caught, and propogates upward.

In the following subsection, we present some examples in order to demonstrate the try-catch functionality.

Example 1

(: Simple try-catch example :)
try {
    3 + "2"
} catch(err:XPTY0004) {
    "Caught a type error"
}

Example 2

(: try-catch with multiple catch clauses showing catch clause precedence :)
try {
    3 + 2 > "30"
} catch(err:XQDY0004) {
    "Some random error that does not occur"
} catch(*, $code) {
    concat("Caught ", $code)
} catch(err:XPTY0004) {
    "This is the error throw. But it should be caught in the catch clause above"
}

Example 3

(: Use of the description variable in the catch clause :)
try {
    2 + "3"
} catch(*, $ecode, $desc) {
    string-join(($ecode, $desc), " ")
}

Example 4

(: Nested try-catch with the use of the error object :)
try {
    for $x in (1, 2, 3, "4", 5)
    return
        try {
            $x + 4
        } catch(err:XPTY0004) {
            fn:error(xs:QName("err:XPTY0004"), "Rethrowing the exception", $x)
        }
} catch(*, $code, $desc, $obj) {
    string-join(("An error was caught: ", $code, "Description:", $desc, " The cause was:", $obj), " ")
}

Example 5

(: try-catch catching error happening inside functions :)

declare function local:squares() {
    for $x in (1, 2, 3, 4, "5", 6, 7)
    return $x * $x
};

try {
    local:squares()
} catch(err:XPTY0004) {
    "Caught a type error"
}

Example 5

let $x := 1 div 0
return
  try { 
    $x 
  } catch (*) { "This catch clause won't fire." }