LOGBACK-543 Use Throwable.toString by bjkail · Pull Request #404 · qos-ch/logback (original) (raw)

I'd like to add another real-world example where this behavior causes problems.

org.xml.sax.SAXParseException overrides toString() to include the lineNumber and columnNumber where the parsing error occurred:

    public String toString() {
        StringBuilder buf = new StringBuilder(getClass().getName());
        String message = getLocalizedMessage();
        if (publicId!=null)    buf.append("publicId: ").append(publicId);
        if (systemId!=null)    buf.append("; systemId: ").append(systemId);
        if (lineNumber!=-1)    buf.append("; lineNumber: ").append(lineNumber);
        if (columnNumber!=-1)  buf.append("; columnNumber: ").append(columnNumber);

       //append the exception message at the end
        if (message!=null)     buf.append("; ").append(message);
        return buf.toString();
    }

Example output:

org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 37; cvc-datatype-valid.1.2.1: 'undefined' is not a valid value for 'integer'.

Its getMessage() implementation lacks this information (inherited from SAXException):

    public String getMessage ()
    {
        String message = super.getMessage();
        Throwable cause = super.getCause();

        if (message == null && cause != null) {
            return cause.getMessage();
        } else {
            return message;
        }
    }

When logback logs this exception using className + ": " + getMessage(), the location information is lost:

org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'undefined' is not a valid value for 'integer'.

For XML validation errors, knowing the exact line and column number is very helpful for debugging. Without it, finding the offending element in a large XML document becomes significantly harder.

We only discovered this issue because we had a second log file that used Throwable.printStackTrace() directly, which calls toString() and preserved the location. Otherwise, this diagnostic information would have been silently discarded.

This is a case where logback could improve debuggability similar to both log4j and standard printStackTrace() output.