diff --git a/python/pyspark/sql/tests/test_utils.py b/python/pyspark/sql/tests/test_utils.py index fdadd5631c..072ea08085 100644 --- a/python/pyspark/sql/tests/test_utils.py +++ b/python/pyspark/sql/tests/test_utils.py @@ -1,3 +1,4 @@ +# -*- encoding: utf-8 -*- # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with @@ -26,6 +27,12 @@ class UtilsTests(ReusedSQLTestCase): self.assertRaises(AnalysisException, lambda: self.spark.sql("select abc")) self.assertRaises(AnalysisException, lambda: self.df.selectExpr("a + b")) + def test_capture_user_friendly_exception(self): + try: + self.spark.sql("select `中文字段`") + except AnalysisException as e: + self.assertRegexpMatches(str(e), "cannot resolve '`中文字段`'") + def test_capture_parse_exception(self): self.assertRaises(ParseException, lambda: self.spark.sql("abc")) diff --git a/python/pyspark/sql/utils.py b/python/pyspark/sql/utils.py index c30cc14827..996b7dd59c 100644 --- a/python/pyspark/sql/utils.py +++ b/python/pyspark/sql/utils.py @@ -16,6 +16,7 @@ # import py4j +import sys class CapturedException(Exception): @@ -25,7 +26,12 @@ class CapturedException(Exception): self.cause = convert_exception(cause) if cause is not None else None def __str__(self): - return repr(self.desc) + desc = self.desc + # encode unicode instance for python2 for human readable description + if sys.version_info.major < 3 and isinstance(desc, unicode): + return str(desc.encode('utf-8')) + else: + return str(desc) class AnalysisException(CapturedException):