Description
The query plan in an AnalysisException may be null when an AnalysisException object is serialized and then deserialized, since plan is marked @transient. Or when someone throws an AnalysisException with a null query plan (which should not happen).
def getMessage is not tolerant of this and throws a NullPointerException, leading to loss of information about the original exception.
The fix is to add a null check in getMessage.