|
31 | 31 | import net.sf.saxon.Configuration;
|
32 | 32 | import net.sf.saxon.expr.parser.RetainedStaticContext;
|
33 | 33 | import net.sf.saxon.functions.SystemProperty;
|
| 34 | +import net.sf.saxon.om.StructuredQName; |
34 | 35 | import net.sf.saxon.s9api.*;
|
35 | 36 | import net.sf.saxon.serialize.SerializationProperties;
|
36 | 37 | import net.sf.saxon.trans.UncheckedXPathException;
|
@@ -177,23 +178,53 @@ private XsltExecutable compileExecutable(final Options options) throws XPathExce
|
177 | 178 | FnTransform.ERROR_LISTENER.clear();
|
178 | 179 | return xsltCompiler.compile(options.xsltSource._2); // .compilePackage //TODO(AR) need to implement support for xslt-packages
|
179 | 180 | } catch (final SaxonApiException e) {
|
180 |
| - Throwable cause = e.getCause(); |
181 |
| - while (cause != null) { |
182 |
| - if (cause instanceof XPathException) { |
183 |
| - //Generated by us, possibly in URI resolution, above - throw it directly |
184 |
| - throw (XPathException) cause; |
185 |
| - } |
186 |
| - cause = cause.getCause(); |
187 |
| - } |
| 181 | + //Generated by us, possibly in URI resolution, above - throw it directly |
| 182 | + throwOriginalXPathException(e, ErrorCodes.FOXT0003); |
188 | 183 | final Optional<TransformerException> compilerException = FnTransform.ERROR_LISTENER.getWorst();
|
189 | 184 | if (compilerException.isPresent()) {
|
190 |
| - throw new XPathException(this, ErrorCodes.FOXT0003,compilerException.get()); |
| 185 | + throwOriginalXPathException(compilerException.get(), ErrorCodes.FOXT0003); |
| 186 | + throw new XPathException(this, ErrorCodes.FOXT0003, compilerException.get()); |
191 | 187 | }
|
192 | 188 | //Wrap any other error
|
193 | 189 | throw new XPathException(this, ErrorCodes.FOXT0003, e.getMessage());
|
194 | 190 | }
|
195 | 191 | }
|
196 | 192 |
|
| 193 | + /** |
| 194 | + * Search for an XPathException in the cause chain, and return it "directly" |
| 195 | + * Either an eXist XPathException, which is immediate |
| 196 | + * Or a Saxon XPathException, when we convert it to something similar in eXist. |
| 197 | + * |
| 198 | + * @param e the top of the exception stack |
| 199 | + * @param defaultErrorCode use this code and its description to fill in blanks in what we finally throw |
| 200 | + * @throws XPathException the eventual eXist exception we may throw |
| 201 | + */ |
| 202 | + private void throwOriginalXPathException(final Throwable e, final ErrorCodes.ErrorCode defaultErrorCode) throws XPathException { |
| 203 | + Throwable cause = e; |
| 204 | + while (cause != null) { |
| 205 | + if (cause instanceof XPathException) { |
| 206 | + throw (XPathException) cause; |
| 207 | + } |
| 208 | + cause = cause.getCause(); |
| 209 | + } |
| 210 | + |
| 211 | + cause = e; |
| 212 | + while (cause != null) { |
| 213 | + if (cause instanceof net.sf.saxon.trans.XPathException) { |
| 214 | + final net.sf.saxon.trans.XPathException xPathException = (net.sf.saxon.trans.XPathException)cause; |
| 215 | + final StructuredQName from = xPathException.getErrorCodeQName(); |
| 216 | + if (from != null) { |
| 217 | + final QName errorCodeQName = new QName(from.getLocalPart(), from.getURI(), from.getPrefix()); |
| 218 | + final ErrorCodes.ErrorCode errorCode = new ErrorCodes.ErrorCode(errorCodeQName, defaultErrorCode.getDescription()); |
| 219 | + throw new XPathException(errorCode, cause.getMessage()); |
| 220 | + } else { |
| 221 | + throw new XPathException(this, defaultErrorCode, cause.getMessage()); |
| 222 | + } |
| 223 | + } |
| 224 | + cause = cause.getCause(); |
| 225 | + } |
| 226 | + } |
| 227 | + |
197 | 228 | /**
|
198 | 229 | * Hash on the options used to create a compiled executable
|
199 | 230 | * Hash should match only when the executable can be re-used.
|
|
0 commit comments