/* * eXist Open Source Native XML Database * Copyright (C) 2010 The eXist Project * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.exist.xquery.functions.xquery3; import org.custommonkey.xmlunit.XMLUnit; import org.custommonkey.xmlunit.XMLAssert; import org.exist.test.ExistXmldbEmbeddedServer; import org.junit.ClassRule; import org.xml.sax.SAXException; import org.xmldb.api.base.ResourceSet; import org.exist.xquery.ErrorCodes; import org.exist.xquery.XPathException; import org.junit.Test; import org.xmldb.api.base.XMLDBException; import java.io.IOException; import static org.junit.Assert.*; /** * @author wessels */ public class TryCatchTest { @ClassRule public static final ExistXmldbEmbeddedServer existEmbeddedServer = new ExistXmldbEmbeddedServer(false, true); @Test public void encapsulated_1() throws XMLDBException { final String query1 = "xquery version '3.0';" + "<a>{ try { 'b' + 7 } catch * { 'c' } }</a>"; final ResourceSet results = existEmbeddedServer.executeQuery(query1); final String r = (String) results.getResource(0).getContent(); assertEquals("<a>c</a>", r); } @Test public void encapsulated_2() throws XMLDBException { final String query1 = "xquery version '3.0';" + "for $i in (1,2,3,4) return <a>{ try { 'b' + $i } catch * { 'c' } }</a>"; final ResourceSet results = existEmbeddedServer.executeQuery(query1); assertEquals(4, results.getSize()); final String r = (String) results.getResource(0).getContent(); assertEquals("<a>c</a>", r); } @Test public void encapsulated_3() throws XMLDBException, IOException, SAXException { final String query1 = "xquery version '3.0';" + "<foo>{ for $i in (1,2,3,4) return <a>{ try { 'b' + $i } catch * { 'c' } }</a> }</foo>"; final ResourceSet results = existEmbeddedServer.executeQuery(query1); assertEquals(1, results.getSize()); final String r = (String) results.getResource(0).getContent(); XMLUnit.setIgnoreWhitespace(true); XMLAssert.assertXMLEqual("<foo><a>c</a><a>c</a><a>c</a><a>c</a></foo>", r); } @Test public void xQuery3_1() throws XMLDBException { final String query1 = "xquery version '1.0';" + "try { a + 7 } catch * { 1 }"; try { final ResourceSet results = existEmbeddedServer.executeQuery(query1); final String r = (String) results.getResource(0).getContent(); assertEquals("1", r); fail("exception expected"); } catch (final Throwable t) { final Throwable cause = t.getCause(); if (cause instanceof XPathException) { final XPathException ex = (XPathException) cause; assertEquals("exerr:EXXQDY0003", ex.getErrorCode().getErrorQName().getStringValue()); } else { throw t; } } } @Test public void simpleCatch() throws XMLDBException { final String query = "xquery version '3.0';" + "try { a + 7 } catch * { 1 }"; final ResourceSet results = existEmbeddedServer.executeQuery(query); final String r = (String) results.getResource(0).getContent(); assertEquals("1", r); } @Test public void catchWithCodeAndDescription() throws XMLDBException { final String query = "xquery version '3.0';" + "try { a + 7 } " + "catch * " + "{ $err:code, $err:description } "; final ResourceSet results = existEmbeddedServer.executeQuery(query); assertEquals(2, results.getSize()); final String r1 = (String) results.getResource(0).getContent(); assertEquals(ErrorCodes.XPDY0002.getErrorQName().getStringValue(), r1); final String r2 = (String) results.getResource(1).getContent(); assertEquals(ErrorCodes.XPDY0002.getDescription() + " Undefined context sequence for 'child::{}a'", r2); } @Test public void catchWithError3Matches() throws XMLDBException { final String query = "xquery version '3.0';" + "try { a + 7 } " + "catch err:XPDY0001 { 1 }" + "catch err:XPDY0002 { 2 }" + "catch err:XPDY0003 { 3 }"; final ResourceSet results = existEmbeddedServer.executeQuery(query); final String r = (String) results.getResource(0).getContent(); assertEquals("2", r); } @Test(expected = XMLDBException.class) public void catchWithErrorNoMatches() throws XMLDBException { final String query = "xquery version '3.0';" + "try { a + 7 } " + "catch err:XPDY0001 { 1 }" + "catch err:XPDY0002 { a }" + "catch err:XPDY0003 { 3 }"; final ResourceSet results = existEmbeddedServer.executeQuery(query); final String r = (String) results.getResource(0).getContent(); assertEquals("2", r); } @Test public void catchWithMultipleMatches() throws XMLDBException { final String query1 = "xquery version '3.0';" + "try { a + 7 } " + "catch err:XPDY0001 | err:XPDY0003 { 13 }" + "catch err:XPDY0002 { 2 }" + "catch err:XPDY0004 | err:XPDY0005 { 45 }"; final ResourceSet results = existEmbeddedServer.executeQuery(query1); final String r = (String) results.getResource(0).getContent(); assertEquals("2", r); final String query2 = "xquery version '3.0';" + "try { a + 7 } " + "catch err:XPDY0001 | * { 13 }" + "catch err:XPDY0002 { 2 }" + "catch err:XPDY0004 | err:XPDY0005 { 45 }"; final ResourceSet results2 = existEmbeddedServer.executeQuery(query2); final String r2 = (String) results2.getResource(0).getContent(); assertEquals("13", r2); } @Test public void catchFnError() throws XMLDBException { final String query1 = "xquery version '3.0';" + "try {" + " fn:error( fn:QName('http://www.w3.org/2005/xqt-errors', 'err:FOER0000') ) " + "} catch * " + "{ $err:code }"; final ResourceSet results = existEmbeddedServer.executeQuery(query1); assertEquals(1, results.getSize()); final String r1 = (String) results.getResource(0).getContent(); assertEquals("err:FOER0000", r1); final String query2 = "xquery version '3.0';" + "try {" + " fn:error( fn:QName('http://www.w3.org/2005/xqt-errors', 'err:FOER0000') ) " + "} catch * " + "{ $err:code }"; final ResourceSet results2 = existEmbeddedServer.executeQuery(query2); assertEquals(1, results2.getSize()); final String r2 = (String) results2.getResource(0).getContent(); assertEquals("err:FOER0000", r2); final String query3 = "xquery version '3.0';" + "try {" + " fn:error(fn:QName('http://www.w3.org/2005/xqt-errors', 'err:FOER0000'), 'TEST') " + "} catch * " + "{ $err:code, $err:description }"; final ResourceSet results3 = existEmbeddedServer.executeQuery(query3); assertEquals(2, results3.getSize()); final String r31 = (String) results3.getResource(0).getContent(); assertEquals("err:FOER0000", r31); final String r32 = (String) results3.getResource(1).getContent(); assertEquals("TEST", r32); final String query4 = "xquery version '3.0';" + "try {" + " fn:error(fn:QName('http://www.w3.org/2005/xqt-errors', 'err:FOER0000'), 'TEST') " + "} catch * " + "{ $err:code, $err:description }"; final ResourceSet results4 = existEmbeddedServer.executeQuery(query4); assertEquals(2, results4.getSize()); final String r41 = (String) results4.getResource(0).getContent(); assertEquals("err:FOER0000", r41); final String r42 = (String) results4.getResource(1).getContent(); assertEquals("TEST", r42); final String query5 = "xquery version '3.0';" + "try {" + " fn:error(fn:QName('http://www.w3.org/2005/xqt-errors', 'err:FOER0000'), 'TEST', <ab/>) " + "} catch * " + "{ $err:code, $err:description, $err:value }"; final ResourceSet results5 = existEmbeddedServer.executeQuery(query5); assertEquals(3, results5.getSize()); final String r51 = (String) results5.getResource(0).getContent(); assertEquals("err:FOER0000", r51); final String r52 = (String) results5.getResource(1).getContent(); assertEquals("TEST", r52); final String r53 = (String) results5.getResource(2).getContent(); assertEquals("<ab/>", r53); } @Test public void catchFullErrorCode() throws XMLDBException { final String query = "xquery version '3.0';" + "try { a + 7 } " + "catch * " + "{ $err:code, $err:description, empty($err:value) } "; final ResourceSet results = existEmbeddedServer.executeQuery(query); assertEquals(3, results.getSize()); final String r1 = (String) results.getResource(0).getContent(); assertEquals(ErrorCodes.XPDY0002.getErrorQName().getStringValue(), r1); final String r2 = (String) results.getResource(1).getContent(); assertEquals(ErrorCodes.XPDY0002.getDescription() + " Undefined context sequence for 'child::{}a'", r2); final String r3 = (String) results.getResource(2).getContent(); assertEquals("true", r3); } @Test public void catchDefinedNamespace() throws XMLDBException { final String query1 = "xquery version '3.0';" + "declare namespace foo='http://foo.com'; " + "try { " + " fn:error(fn:QName('http://foo.com', 'ERRORNAME'), 'ERRORTEXT') " + "} " + "catch foo:ERRORNAME { 'good' } " + "catch * { 'bad' } "; final ResourceSet results = existEmbeddedServer.executeQuery(query1); assertEquals(1, results.getSize()); final String r1 = (String) results.getResource(0).getContent(); assertEquals("good", r1); final String query2 = "xquery version '3.0';" + "declare namespace foo='http://foo.com'; " + "try { " + " fn:error(fn:QName('http://foo.com', 'ERRORNAME'), 'ERRORTEXT') " + "} " + "catch foo:ERRORNAME { $err:code } " + "catch * { 'bad' } "; final ResourceSet results2 = existEmbeddedServer.executeQuery(query2); assertEquals(1, results2.getSize()); final String r2 = (String) results2.getResource(0).getContent(); assertEquals("foo:ERRORNAME", r2); } @Test public void catchDefinedNamespace2() throws XMLDBException { final String query = "xquery version '3.0';" + "declare namespace foo='http://foo.com'; " + "try { " + " fn:error(fn:QName('http://foo.com', 'ERRORNAME'), 'ERRORTEXT')" + "} " + "catch foo:ERRORNAME { 'good' } " + "catch * { 'wrong' } "; final ResourceSet results = existEmbeddedServer.executeQuery(query); assertEquals(1, results.getSize()); final String r1 = (String) results.getResource(0).getContent(); assertEquals("good", r1); } }