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.