Project

Profile

Help

Bug #4239

closed

When using a JAXP SchemaFactory, an error in the schema goes unreported

Added by Michael Kay almost 5 years ago. Updated almost 5 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Diagnostics
Sprint/Milestone:
-
Start date:
2019-06-21
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
9.9, trunk
Fix Committed on Branch:
9.9, trunk
Fixed in Maintenance Release:
Platforms:

Description

Junit test case testValidator/testByteCodeJaxp

If there is an error in the schema (such as Cannot reference schema components in namespace http://myexample/family\ as it has not been imported) this goes unreported. All we get is an exception at the end of processing saying one error was reported.

The error finds its way to the fatalError() method of the (so-called) DRACONIAN_ERROR_HANDLER in SchemaFactoryImpl -- which for some reason ignores it.

Actions #1

Updated by Michael Kay almost 5 years ago

The spec for SchemaFactory.setErrorHandler() says:

When the ErrorHandler is null, the implementation will behave as if the following ErrorHandler is set:

 class DraconianErrorHandler implements ErrorHandler {
     public void fatalError( SAXParseException e ) throws SAXException {
         throw e;
     }
     public void error( SAXParseException e ) throws SAXException {
         throw e;
     }
     public void warning( SAXParseException e ) throws SAXException {
         // noop
     }
 }

We seem to have mis-implemented this.

Actions #2

Updated by Michael Kay almost 5 years ago

Unfortunately, fixing fatalError() to throw the exception doesn't solve the problem, because DelegatingErrorListener promptly ignores it.

It's not actually clear why we're calling fatalError() here rather than error() in the first place. But ignoring the exception thrown by the fatalError() callback seems wrong,

Actions #3

Updated by Michael Kay almost 5 years ago

Although the JAXP SchemaFactory uses an ErrorHandler for reporting schema errors, the SchemaFactory spec says nothing about whether they should be reported using the error() or fatalError() callback; meanwhile the spec for ErrorHandler itself is wrtten as if the class is only used for XML parsing, and it has nothing to say about its use during schema processing.

Actions #4

Updated by Michael Kay almost 5 years ago

As a rare departure from my usual principles, I decided that the spec here was so outrageously defective that the only sensible thing is to find out what Xerces does and do the same. Xerces reports static errors in the schema to the ErrorListener's error() method, rather than to fatalError(), and I think it makes sense to do the same.

This still leaves open the question of how we handle the "draconian" case where the error reporter throws an error.

Actions #5

Updated by Michael Kay almost 5 years ago

Looking now at a schema that contains a couple of "unresolved reference" errors. Saxon reports these to ErrorHandler.warning(), on the basis of the rule in XSD 1.0 (clarified in 1.1) that an unresolved reference is not in itself a hard error. But Xerces reports these to ErrorHandler.error().

Contrariwise, at the end of schema processing, Saxon exits from the newSchema() call with a SAXException, whereas Xerces does a normal exit.

JAXP says "If the parsed set of schemas includes error(s) as specified in the section 5.1 of the XML Schema spec, then the error must be reported to the ErrorHandler."

JAXP also says " after an error is reported to a handler, the callee is allowed to abort the further processing by throwing it." So it seems that throwing a final exception is optional if there have been errors.

But a dangling component reference, according to ยง5.3, is NOT such an error, and Xerces appears to be out-of-line in reporting it as such. So once again, blindly following Xerces doesn't seem the right approach. Equally, if we're reporting it as a warning, then it's not clear why we're throwing an exception at the end.

The problem seems to be that Saxon is reporting a warning for ALL dangling-component errors, but some of these are in fact fatal. For example, we can't cope with declaring a type whose base type is unknown. We're slowly digging ourselves deeper into this hole...

Actions #6

Updated by Michael Kay almost 5 years ago

I'm making three changes:

(a) SchemaFactoryImpl.DRACONIAN_ERROR_HANDLER is aligned with the JAXP spec of the error handler used when no other is provided; specifically, the fatalError() method always throws an exception.

(b) The DelegatingErrorListener is changed so that if the underlying ErrorListener throws an exception P from its error() or fatalError() methods, an unchecked exception (wrapping exception P) is thrown; in the case of EnterpriseConfiguration.addSchemaSource() this unchecked exception is caught and turned into an checked exception from the addSchemaSource() method.

(c) SchemaElement.error() notifies the error to the ErrorListener's error() method rather than fatalError().

Actions #7

Updated by Michael Kay almost 5 years ago

  • Category set to Diagnostics
  • Status changed from New to Resolved
  • Priority changed from Low to Normal
  • Fix Committed on Branch 9.9, trunk added
Actions #8

Updated by O'Neil Delpratt almost 5 years ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 9.9.1.4 added

Bug fix applied in the Saxon 9.9.1.4 maintenance release

Please register to edit this issue

Also available in: Atom PDF