URI Resolver Exceptions not handled Correctly
Added by Anonymous almost 16 years ago
Legacy ID: #5845294 Legacy Poster: Andrew Waters (andrew_waters)
Hi, I think I've discovered a bug in the way exceptions are handled by one of the URI Resolver methods. One method can raise an exception and the caller can access it and its messages and all looks well. The other has it's exception "semi-ignored" and Saxon then returns an error for the next line which is actually totally valid. Here's some java to recreate: package saxontest; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.io.StringWriter; import java.util.Properties; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import net.sf.saxon.Configuration; import net.sf.saxon.query.DynamicQueryContext; import net.sf.saxon.query.ModuleURIResolver; import net.sf.saxon.query.StaticQueryContext; import net.sf.saxon.query.XQueryExpression; import net.sf.saxon.trans.XPathException; import com.att.logicalprovisioning.xquery.SaxonErrorListener; public class SaxonBug1 implements URIResolver, ModuleURIResolver { /** * / private static final long serialVersionUID = 1L; // Set a version string from CVS for easy runtime identification public static final String cvsVersionId = "$Revision$ $Date$ $Name$"; private ByteArrayOutputStream errors = new ByteArrayOutputStream(); private Configuration saxonConfig = new Configuration(); /* * @param args */ public static void main(String[] args) { String xml1 = "xquery version "1.0";"; xml1 += "declare variable $nc3 := 'file:///c:/pmm_test/fail';"; xml1 += "$nc3"; String xml2 = "xquery version "1.0";"; xml2 += "declare variable $nc3 := doc('file:///c:/pmm_test/fail');"; xml2 += "$nc3"; String xml3 = "xquery version "1.0";"; xml3 += "import module namespace fail = "fail" at "fail";"; xml3 += "declare variable $nc3 := doc('file:///c:/pmm_test/fail');"; xml3 += "$nc3"; SaxonBug1 sb1 = new SaxonBug1(); System.out.println("xml 1 = OK - XML produced :: " + sb1.runXQuery(xml1)); System.out.println("\n\nxml 2 = OK - exception works :: " + sb1.runXQuery(xml2)); System.out.println("\n\nxml 3 = OOOERR!!!!!!!!! :: " + sb1.runXQuery(xml3)); System.out.println(net.sf.saxon.Version.getProductTitle()); } public String runXQuery(String xQuery) { String xqResult = ""; // Ensure that the XQuery is not null if ((xQuery == null) || (xQuery.length() == 0)) return "Null/empty XQuery when calling Saxon. An XQuery must be provided"; try { // Prepare the environment for Saxon SaxonErrorListener listener = new SaxonErrorListener(new PrintStream(errors)); getSaxonConfig().setErrorListener(listener); StaticQueryContext staticContext = new StaticQueryContext(getSaxonConfig()); staticContext.setBaseURI(""); // Set up the dynamic context DynamicQueryContext dynamicContext = new DynamicQueryContext(getSaxonConfig()); dynamicContext.setURIResolver(this); staticContext.setModuleURIResolver(this); Properties saxonProps = new Properties(); // Prepare the XQuery XQueryExpression exp; exp = staticContext.compileQuery(xQuery); // Run the XQuery StringWriter out = new StringWriter(); exp.run(dynamicContext, new StreamResult(out), saxonProps); // Collect the content xqResult = out.toString(); } catch (XPathException xpe) { String cause = "Unknown - !!!"; if (xpe.getCause() != null) cause = xpe.getCause().getMessage(); String msg = xpe.getMessageAndLocation(); return "Exception while calling Saxon: " + msg + "; Cause: " + cause; } catch (Exception e) { return "Exception while calling Saxon: " + e.getMessage(); } return xqResult; } private Configuration getSaxonConfig() { return saxonConfig; } public Source resolve(String href, String base) throws TransformerException { if (true) throw new XPathException("resolve 1 exception"); return null; } public StreamSource[] resolve(String arg0, String arg1, String[] arg2) throws XPathException { if (true) throw new XPathException("resolve 2 exception"); return null; } } Sample output: xml 1 = OK - XML produced :: <?xml version="1.0" encoding="UTF-8"?>file:///c:/pmm_test/fail xml 2 = OK - exception works :: Exception while calling Saxon: Exception thrown by URIResolver; SystemID: ; Line#: 1; Column#: -1; Cause: resolve 1 exception xml 3 = OOOERR!!!!!!!!! :: Exception while calling Saxon: XQuery static error in #...ile:///c:/pmm_test/fail');$nc3#: Variable $nc3 has not been declared; SystemID: ; Line#: 1; Column#: 130; Cause: Unknown - !!! SAXON 9.1.0.3 from Saxonica
Replies (5)
Please register to reply
RE: URI Resolver Exceptions not handled Correctly - Added by Anonymous almost 16 years ago
Legacy ID: #6440547 Legacy Poster: Andrew Waters (andrew_waters)
Hi, Is this a valid bug report? I did test with 9.1.0.4 too. Do I need to try with another release? Thanks. Andrew.
RE: URI Resolver Exceptions not handled Correctly - Added by Anonymous almost 16 years ago
Legacy ID: #6447619 Legacy Poster: Michael Kay (mhkay)
Sorry not to respond to this when originally raised, it must have got lost in the Christmas rush. No, I don't think there's a bug here. The exception thrown by the URIResolver is a dynamic error; dynamic errors are generally fatal and result in immediate termination. The exception thrown by the ModuleURIResolver is a compile-time error; the general strategy with compile-time errors is to report the error (to the ErrorListener) and attempt to continue the compilation by detecting as many errors as you can in a single compilation run. The error recovery here isn't quite as good as it should be, because it causes the variable declaration to be skipped, which leads to a spurious error when the variable is referenced. I'll try to improve that, but syntax error recovery is not a precise art, and I don't regard a failure to recover perfectly in every case as a bug.
RE: URI Resolver Exceptions not handled Correctly - Added by Anonymous almost 16 years ago
Legacy ID: #6449050 Legacy Poster: Andrew Waters (andrew_waters)
Michael, No problem and thanks for the response. The thing is the text of the exception thrown by ModuleURIResolver is not even "logged" so even though the final "exception" is "misleading" there are no other clues in the output. Isn't that a "bug"? I'll throw a spanner in here (for what it's worth :-) ) and suggest that if there is an error in ModuleURIResolver then the "absence" of the correct imported modules is likely to lead to potentially quite a few compile errors that are not "true" errors. Maybe this could be treated as a fatal error??? On the other hand of course the missing module could result in very few (or even no) errors too....a dilemma I guess :-) Andrew.
RE: URI Resolver Exceptions not handled Correctly - Added by Anonymous almost 16 years ago
Legacy ID: #6449297 Legacy Poster: Michael Kay (mhkay)
The exception thrown by the ModuleURIResolver is reported to the ErrorListener, like all other compile-time errors. The standard error listener reports it to System.err. Your code was running with a custom ErrorListener, which you didn't include, so I don't know what it would do with it. It's true that a missing module could lead to lots of consequent errors: just as a misspelt variable name or function name in a declaration could. I think that in general it's best to carry on compiling if you can.
RE: URI Resolver Exceptions not handled Correctly - Added by Anonymous almost 16 years ago
Legacy ID: #6449661 Legacy Poster: Andrew Waters (andrew_waters)
oooops Well spotted - I didn't realise I'd copied that from my "production" code to make up this test class. I humbly grovel and crawl back into my deep dark hole..... Andrew.
Please register to reply