Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

Emanuel Wlaschitz

I just came across a faulty template in one of our stylesheets that does not correctly check for the presence of a unit and tries to convert/do maths with the input string.

As a result, we see a Saxon.Api.DynamicError with the message 'For input string: "18pt"' (and nothing else).

On stdout (or stderr, not sure on that console) we get a pretty nice stack trace of where the issue actually happens:

 

Validation error at xsl:value-of on line 429 of tables.xsl:

  FORG0001: For input string: "18pt"

  at xsl:call-template name="getPointWidth" (file://path/to/tables.xsl#120)

  [... more stack frames here ...]

 

I found another ML post from 2012 about capturing the result of a validation from code; but this relates to SchemaValidator which has a method setErrorListener that seems to do exactly that.

This doesn't seem to apply to the .NET XsltTransformer (nor its Java implementation net.sf.saxon.Controller which does have a setErrorListener method, but only returns the same string as the DynamicError in its ErrorListener.fatalError callback) with Saxon-HE 9.6N (.NET)

XsltTransformer.MessageListener only returns xsl:message, XsltTransformer.TraceFunctionDestination only gets trace(), and XsltTransformer.Implementation.setErrorListener isn't quite correct either.

 

What options do I have in .NET to get those information for further processing (such as writing it to a log, populating my own exception type intended for the developer, or whatever else I could think of); or am I simply looking in the wrong place?

 

Kind regards, Emanuel


------------------------------------------------------------------------------

_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

Michael Kay
We don’t provide an ErrorListener on the .NET XsltTransformer (or Xslt30Transformer) primarily because a listener interface really doesn’t make very much sense where only one dynamic error can occur, and the details of the error are (in principle) all available in the exception thrown by the transform() method (or equivalent). This should be an instance of DynamicError, though of course in the .NET API (unlike Java) exceptions aren’t part of the function signature so the documentation doesn’t make this totally obvious.

The DynamicError wraps a (Java) XPathException, but unfortunately it doesn’t expose an escape-hatch method to get the underlying XPathException. It makes most of the information in the XPathException available, but not the XPathContext, which is what we use to produce the stack trace. To get to the XPathException directly you would need to get the Controller underpinning the XsltTransformer and register an ErrorListener with the Controller.

The code for generating the stack trace is in the static (Java) method StandardErrorListener.printStackTrace(Logger, XPathContext). You could change the destination of the tracing by substituting or configuring the Logger, or you could look at the code of the method and see how to make the stack trace available programmatically rather than printing it out.

I think that exposing a .NET API to give programmatic access to the stack trace would probably be a bit over the top, but it would probably be reasonable to provide something like DynamicError.PrintStackTrace(Stream), as well as an escape-hatch from DynamicError to the contained XPathException.

Michael Kay
Saxonica


On 2 Jun 2015, at 10:52, Emanuel Wlaschitz <[hidden email]> wrote:

I just came across a faulty template in one of our stylesheets that does not correctly check for the presence of a unit and tries to convert/do maths with the input string.

As a result, we see a Saxon.Api.DynamicError with the message 'For input string: "18pt"' (and nothing else).

On stdout (or stderr, not sure on that console) we get a pretty nice stack trace of where the issue actually happens:

 

Validation error at xsl:value-of on line 429 of tables.xsl:

  FORG0001: For input string: "18pt"

  at xsl:call-template name="getPointWidth" (file://path/to/tables.xsl#120)

  [... more stack frames here ...]

 

I found another ML post from 2012 about capturing the result of a validation from code; but this relates to SchemaValidator which has a method setErrorListener that seems to do exactly that.

This doesn't seem to apply to the .NET XsltTransformer (nor its Java implementation net.sf.saxon.Controller which does have a setErrorListener method, but only returns the same string as the DynamicError in its ErrorListener.fatalError callback) with Saxon-HE 9.6N (.NET)

XsltTransformer.MessageListener only returns xsl:message, XsltTransformer.TraceFunctionDestination only gets trace(), and XsltTransformer.Implementation.setErrorListener isn't quite correct either.

 

What options do I have in .NET to get those information for further processing (such as writing it to a log, populating my own exception type intended for the developer, or whatever else I could think of); or am I simply looking in the wrong place?

 

Kind regards, Emanuel

------------------------------------------------------------------------------
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help


------------------------------------------------------------------------------

_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

Emanuel Wlaschitz

I already tried messing around with the controller, but the ErrorListener interface only provides a warning/error/fatalError method with a TransformerException parameter - none of which seem to expose an XPathContext.

 

But thanks anyways, I'll be patient and see what the future brings.

 

DynamicError does include the file name and line number; but my error message was off since there was a warning in front of the actual message (hiding the correct location).

That's a different thing tho; and if I find the time to make a small repro-case, I'll throw it at the bug tracker directly.

 

Regards, Emanuel

 

From: Michael Kay [mailto:[hidden email]]
Sent: Dienstag, 02. Juni 2015 12:45
To: Mailing list for the SAXON XSLT and XQuery processor
Subject: Re: [saxon] Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

 

We don’t provide an ErrorListener on the .NET XsltTransformer (or Xslt30Transformer) primarily because a listener interface really doesn’t make very much sense where only one dynamic error can occur, and the details of the error are (in principle) all available in the exception thrown by the transform() method (or equivalent). This should be an instance of DynamicError, though of course in the .NET API (unlike Java) exceptions aren’t part of the function signature so the documentation doesn’t make this totally obvious.

 

The DynamicError wraps a (Java) XPathException, but unfortunately it doesn’t expose an escape-hatch method to get the underlying XPathException. It makes most of the information in the XPathException available, but not the XPathContext, which is what we use to produce the stack trace. To get to the XPathException directly you would need to get the Controller underpinning the XsltTransformer and register an ErrorListener with the Controller.

 

The code for generating the stack trace is in the static (Java) method StandardErrorListener.printStackTrace(Logger, XPathContext). You could change the destination of the tracing by substituting or configuring the Logger, or you could look at the code of the method and see how to make the stack trace available programmatically rather than printing it out.

 

I think that exposing a .NET API to give programmatic access to the stack trace would probably be a bit over the top, but it would probably be reasonable to provide something like DynamicError.PrintStackTrace(Stream), as well as an escape-hatch from DynamicError to the contained XPathException.

 

Michael Kay

Saxonica

 

 

On 2 Jun 2015, at 10:52, Emanuel Wlaschitz <[hidden email]> wrote:

 

I just came across a faulty template in one of our stylesheets that does not correctly check for the presence of a unit and tries to convert/do maths with the input string.

As a result, we see a Saxon.Api.DynamicError with the message 'For input string: "18pt"' (and nothing else).

On stdout (or stderr, not sure on that console) we get a pretty nice stack trace of where the issue actually happens:

 

Validation error at xsl:value-of on line 429 of tables.xsl:

  FORG0001: For input string: "18pt"

  at xsl:call-template name="getPointWidth" (<a href="file:///\\path\to\tables.xsl#120">file://path/to/tables.xsl#120)

  [... more stack frames here ...]

 

I found another ML post from 2012 about capturing the result of a validation from code; but this relates to SchemaValidator which has a method setErrorListener that seems to do exactly that.

This doesn't seem to apply to the .NET XsltTransformer (nor its Java implementation net.sf.saxon.Controller which does have a setErrorListener method, but only returns the same string as the DynamicError in its ErrorListener.fatalError callback) with Saxon-HE 9.6N (.NET)

XsltTransformer.MessageListener only returns xsl:message, XsltTransformer.TraceFunctionDestination only gets trace(), and XsltTransformer.Implementation.setErrorListener isn't quite correct either.

 

What options do I have in .NET to get those information for further processing (such as writing it to a log, populating my own exception type intended for the developer, or whatever else I could think of); or am I simply looking in the wrong place?

 

Kind regards, Emanuel

------------------------------------------------------------------------------
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help

 


------------------------------------------------------------------------------

_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

Michael Kay

On 2 Jun 2015, at 12:06, Emanuel Wlaschitz <[hidden email]> wrote:

I already tried messing around with the controller, but the ErrorListener interface only provides a warning/error/fatalError method with a TransformerException parameter - none of which seem to expose an XPathContext.


The TransformerException will usually be castable to XPathException, and Saxon’s XPathException has a getXPathContext(). Like most getters on XPathException, be aware that it may return null.

 

But thanks anyways, I'll be patient and see what the future brings.

 

DynamicError does include the file name and line number; but my error message was off since there was a warning in front of the actual message (hiding the correct location).

That's a different thing tho; and if I find the time to make a small repro-case, I'll throw it at the bug tracker directly.

 



Always happy to have bugs on bad diagnostics, however trivial they might seem, it’s the only way we can improve them.

Michael Kay
Saxonica


------------------------------------------------------------------------------

_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

Emanuel Wlaschitz

Nice, that looks like something I can work with. Thanks again!

 

Regarding the message being off; this is actually my own fault - that particular case prints all XsltCompiler.ErrorList entries (which contain the warning) and DynamicError.ToString (which, actually, is just the message) leading to some confusion on where the output came from. That's something I need to change on my end, sorry for that.

 

- Emanuel

 

From: Michael Kay [mailto:[hidden email]]
Sent: Dienstag, 02. Juni 2015 13:53
To: Mailing list for the SAXON XSLT and XQuery processor
Subject: Re: [saxon] Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

 

 

On 2 Jun 2015, at 12:06, Emanuel Wlaschitz <[hidden email]> wrote:

 

I already tried messing around with the controller, but the ErrorListener interface only provides a warning/error/fatalError method with a TransformerException parameter - none of which seem to expose an XPathContext.

 

The TransformerException will usually be castable to XPathException, and Saxon’s XPathException has a getXPathContext(). Like most getters on XPathException, be aware that it may return null.

 

But thanks anyways, I'll be patient and see what the future brings.

 

DynamicError does include the file name and line number; but my error message was off since there was a warning in front of the actual message (hiding the correct location).

That's a different thing tho; and if I find the time to make a small repro-case, I'll throw it at the bug tracker directly.

 

 

 

Always happy to have bugs on bad diagnostics, however trivial they might seem, it’s the only way we can improve them.

 

Michael Kay

Saxonica

 


------------------------------------------------------------------------------

_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

Michael Kay
In reply to this post by Emanuel Wlaschitz
(Sorry, I just found that this response doesn’t seem to have gone out).

We haven’t exposed an ErrorListener mechanism on the .NET XsltTransformer (or Xslt30Transformer) because it’s not really very useful for dynamic errors, since there’s normally only one error that can happen, and all the information about it is available in the exception thrown by the call on transform() (or whatever). (We’re also a bit confused about how the ErrorListener should interact with try/catch).

On .NET, of course, exception definitions are not part of the function signature in the same way as on Java, so they perhaps aren’t that clearly documented, but the transform() method should throw a DynamicError. The DynamicError wraps a (Java) XPathException. It doesn’t have an escape-hatch mechanism to get to the XPathException (perhaps it should), but it does expose most of the information in the XPathException object.

The stack trace that you see is produced by the static (Java) method StandardErrorListener.printStackTrace(Logger, XPathContext), and the reference to the XPathContext is (where possible) held in the XPathException, but it’s a reference that we don’t expose.

There’s clearly scope here to do better. I think that exposing a programmatic API to the stack trace on .NET would probably be over-the-top.

Michael Kay
Saxonica



On 2 Jun 2015, at 10:52, Emanuel Wlaschitz <[hidden email]> wrote:

I just came across a faulty template in one of our stylesheets that does not correctly check for the presence of a unit and tries to convert/do maths with the input string.

As a result, we see a Saxon.Api.DynamicError with the message 'For input string: "18pt"' (and nothing else).

On stdout (or stderr, not sure on that console) we get a pretty nice stack trace of where the issue actually happens:

 

Validation error at xsl:value-of on line 429 of tables.xsl:

  FORG0001: For input string: "18pt"

  at xsl:call-template name="getPointWidth" (file://path/to/tables.xsl#120)

  [... more stack frames here ...]

 

I found another ML post from 2012 about capturing the result of a validation from code; but this relates to SchemaValidator which has a method setErrorListener that seems to do exactly that.

This doesn't seem to apply to the .NET XsltTransformer (nor its Java implementation net.sf.saxon.Controller which does have a setErrorListener method, but only returns the same string as the DynamicError in its ErrorListener.fatalError callback) with Saxon-HE 9.6N (.NET)

XsltTransformer.MessageListener only returns xsl:message, XsltTransformer.TraceFunctionDestination only gets trace(), and XsltTransformer.Implementation.setErrorListener isn't quite correct either.

 

What options do I have in .NET to get those information for further processing (such as writing it to a log, populating my own exception type intended for the developer, or whatever else I could think of); or am I simply looking in the wrong place?

 

Kind regards, Emanuel

------------------------------------------------------------------------------
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help


------------------------------------------------------------------------------

_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

Emanuel Wlaschitz

Thanks for the follow-up, Mike!

was able to whip something useful together with the previous infos anyways; for reference it looks as follows:

 

// custom class implementing ErrorListener, and something else deriving from Logger to receive the messages

// (for testing, this was simply done on the same class)

public class CustomErrorListener : Logger, ErrorListener

{

    private readonly ICollection<string> _messages;

    public CustomErrorListener(ICollection<string> messages)

    {

        _messages = messages;

    }

    // other methods omitted

    public void fatalError(TransformerException te)

    {

        var xpe = te as XPathException;

        if (xpe != null)

            StandardErrorListener.printStackTrace(this, xpe.getXPathContext()); // calls Logger.println

        else

            _messages.Add(te.getMessageAndLocation());

    }

    public override void println(string str, int i)

    {

        _messages.Add(string.Format("[{0}] {1}", i, str));

    }

}

 

// in the place where the transformer is used or created

var messages = new List<string>();

transformer.Implementation.setErrorListener(new CustomErrorListener(messages));

 

Suffices for testing and during development, but it might really help to see DynamicError getting the actual XSLT Stacktrace as additional information (since it really helps in finding the offending XSLT module, template and even source context in the input XML file).

 

- Emanuel

 

From: Michael Kay [mailto:[hidden email]]
Sent: Montag, 08. Juni 2015 17:08
To: Mailing list for the SAXON XSLT and XQuery processor
Subject: Re: [saxon] Validation errors during XsltTransformer.Run (on .NET) - can we capture them in code rather than on stdout/stderr?

 

(Sorry, I just found that this response doesn’t seem to have gone out).

 

We haven’t exposed an ErrorListener mechanism on the .NET XsltTransformer (or Xslt30Transformer) because it’s not really very useful for dynamic errors, since there’s normally only one error that can happen, and all the information about it is available in the exception thrown by the call on transform() (or whatever). (We’re also a bit confused about how the ErrorListener should interact with try/catch).

 

On .NET, of course, exception definitions are not part of the function signature in the same way as on Java, so they perhaps aren’t that clearly documented, but the transform() method should throw a DynamicError. The DynamicError wraps a (Java) XPathException. It doesn’t have an escape-hatch mechanism to get to the XPathException (perhaps it should), but it does expose most of the information in the XPathException object.

 

The stack trace that you see is produced by the static (Java) method StandardErrorListener.printStackTrace(Logger, XPathContext), and the reference to the XPathContext is (where possible) held in the XPathException, but it’s a reference that we don’t expose.

 

There’s clearly scope here to do better. I think that exposing a programmatic API to the stack trace on .NET would probably be over-the-top.

 

Michael Kay

Saxonica

 

 

 

On 2 Jun 2015, at 10:52, Emanuel Wlaschitz <[hidden email]> wrote:

 

I just came across a faulty template in one of our stylesheets that does not correctly check for the presence of a unit and tries to convert/do maths with the input string.

As a result, we see a Saxon.Api.DynamicError with the message 'For input string: "18pt"' (and nothing else).

On stdout (or stderr, not sure on that console) we get a pretty nice stack trace of where the issue actually happens:

 

Validation error at xsl:value-of on line 429 of tables.xsl:

  FORG0001: For input string: "18pt"

  at xsl:call-template name="getPointWidth" (<a href="file:///\\path\to\tables.xsl#120">file://path/to/tables.xsl#120)

  [... more stack frames here ...]

 

I found another ML post from 2012 about capturing the result of a validation from code; but this relates to SchemaValidator which has a method setErrorListener that seems to do exactly that.

This doesn't seem to apply to the .NET XsltTransformer (nor its Java implementation net.sf.saxon.Controller which does have a setErrorListener method, but only returns the same string as the DynamicError in its ErrorListener.fatalError callback) with Saxon-HE 9.6N (.NET)

XsltTransformer.MessageListener only returns xsl:message, XsltTransformer.TraceFunctionDestination only gets trace(), and XsltTransformer.Implementation.setErrorListener isn't quite correct either.

 

What options do I have in .NET to get those information for further processing (such as writing it to a log, populating my own exception type intended for the developer, or whatever else I could think of); or am I simply looking in the wrong place?

 

Kind regards, Emanuel

------------------------------------------------------------------------------
_______________________________________________
saxon-help mailing list archived at
http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help

 


------------------------------------------------------------------------------

_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help