Project

Profile

Help

Support #6049

open

Does XQueryEvaluator for SaxonCS lack the API to set an ErrorReporter?

Added by Martin Honnen 11 days ago. Updated 11 days ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
.NET API
Sprint/Milestone:
-
Start date:
2023-05-25
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
12
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:
.NET

Description

In https://saxonica.plan.io/boards/3/topics/9430?r=9432#message-9432 I commented on spurious console error output by SaxonCS while I thought my GUI program caught any SaxonApiExceptions. I managed to prevent lots of those console error outputs by using an ErrorReporter on XsltCompiler, XQueryCompiler and Xslt30Transformer.

However, for XQueryEvaluator in the SaxonCS API, that option seems to be missing and as a result code like

using Saxon.Api;

namespace SaxonCSXQueryEvaluatorLackOfErrorReporter
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var processor = new Processor();

            var xqueryCompiler = processor.NewXQueryCompiler();

            var errorList = new List<string>();

            xqueryCompiler.ErrorReporter = error => errorList.Add($"{error.Message} {error.Location.LineNumber}:{error.Location.ColumnNumber}");

            XQueryExecutable xqueryExecutable = null;
            try
            {
                xqueryExecutable = xqueryCompiler.Compile(".");
            }
            catch (SaxonApiException e)
            {
                Console.WriteLine($"XQuery compilation failed: {e.Message}\n{string.Join('\n', errorList)}");
                return;
            }

            var xqueryEvaluator = xqueryExecutable.Load();

            try
            {
                using var resultWriter = new StringWriter();
                xqueryEvaluator.Run(processor.NewSerializer(resultWriter));
                Console.WriteLine(resultWriter.ToString());
            }
            catch (SaxonApiException e)
            {
                Console.WriteLine($"XQuery evaluation failed: {e.Message}\n{string.Join('\n', errorList)}");
            }

        }
    }
}

outputs both the Console.WriteLine($"XQuery evaluation failed: {e.Message}\n{string.Join('\n', errorList)}"); as well as SaxonCS internal Console.Err output e.g.

Error on line 1 column 2
  XPDY0002  The context item is absent
XQuery evaluation failed: The context item is absent

For a Java program along the same lines I see similar output but there XQueryEvaluator allows me to set an ErrorReporter e.g.

package org.example;

import net.sf.saxon.s9api.*;

import java.io.StringWriter;
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        Processor processor = new Processor();

        XQueryCompiler xqueryCompiler = processor.newXQueryCompiler();

        ArrayList<String> errorList = new ArrayList<>();
        xqueryCompiler.setErrorReporter(xmlProcessingError -> errorList.add(xmlProcessingError.getMessage() + " " + xmlProcessingError.getLocation().getLineNumber() + ":" + xmlProcessingError.getLocation().getColumnNumber()));

        XQueryExecutable xqueryExecutable = null;
        try {
            xqueryExecutable = xqueryCompiler.compile(".");
        }
        catch (SaxonApiException e) {
            System.out.println("XQuery compilation failed: " + e.getMessage() + "\n" + errorList);
            return;
        }

        XQueryEvaluator xqueryEvaluator = xqueryExecutable.load();

        errorList.clear();
        xqueryEvaluator.setErrorReporter(xmlProcessingError -> errorList.add(xmlProcessingError.getMessage() + " " + xmlProcessingError.getLocation().getLineNumber() + ":" + xmlProcessingError.getLocation().getColumnNumber()));
        
        try {
            StringWriter resultWriter = new StringWriter();
            xqueryEvaluator.run(processor.newSerializer(resultWriter));
        }
        catch (SaxonApiException e) {
            System.out.println("XQuery evaluation failed: " + e.getMessage() + "\n" + errorList);
        }

    }
}

and then Saxon's internal output to System.err is prevented.

That suggests SaxonCS somehow lacks the option/API to set an ErrorReporter on XQueryEvaluator.

Or is there a different way for SaxonCS to prevent the Console.Err output and handle any errors with program code?

Actions #1

Updated by Michael Kay 11 days ago

That suggests SaxonCS somehow lacks the option/API to set an ErrorReporter on XQueryEvaluator.

First reaction, it appears to be an oversight.

But actually, I think it might have been deliberate, since the method is also absent from XsltTransformer.

Perhaps I was thinking: run-time errors are always fatal (unless caught by try/catch). They are going to result in an exception, and all the error information should be in the exception. What is achieved by notifying them to an ErrorReporter as well?

This logic doesn't work for warnings, of course.

Or is there a different way for SaxonCS to prevent the Console.Err output and handle any errors with program code?

On the reasoning above, there should be no Console.Err output unless the application writes it. That's in an ideal world, of course. It's hard to be sure it won't happen on some error conditions.

Please register to edit this issue

Also available in: Atom PDF