diff options
| author | Nate Clark <natec425@gmail.com> | 2019-02-20 12:58:18 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-02-20 18:56:47 -0500 |
| commit | 8f318692d4443300c90c7be9dc44ae3c8707f818 (patch) | |
| tree | 3b935eedfd1c31ae4c69c4996f3bae5adec2bd71 /test | |
| parent | d879bed8786b6387b470c148b412731456793653 (diff) | |
| download | sqlalchemy-8f318692d4443300c90c7be9dc44ae3c8707f818.tar.gz | |
Include newlines in StatementError formatting
Revised the formatting for :class:`.StatementError` when stringified. Each
error detail is broken up over multiple newlines instead of spaced out on a
single line. Additionally, the SQL representation now stringifies the SQL
statement rather than using ``repr()``, so that newlines are rendered as is.
Pull request courtesy Nate Clark.
Fixes: #4500
Closes: #4501
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/4501
Pull-request-sha: 60cc0ee68dc96b8f483a60d37bcb26b6c6d53efe
Change-Id: I79d8418b7495e5691c9a56f41e79495c26a967ff
Diffstat (limited to 'test')
| -rw-r--r-- | test/base/test_except.py | 80 | ||||
| -rw-r--r-- | test/engine/test_deprecations.py | 2 | ||||
| -rw-r--r-- | test/engine/test_execute.py | 10 | ||||
| -rw-r--r-- | test/engine/test_logging.py | 10 | ||||
| -rw-r--r-- | test/orm/test_session.py | 2 | ||||
| -rw-r--r-- | test/sql/test_insert_exec.py | 4 |
6 files changed, 65 insertions, 43 deletions
diff --git a/test/base/test_except.py b/test/base/test_except.py index 58943902c..7dcfbb1f0 100644 --- a/test/base/test_except.py +++ b/test/base/test_except.py @@ -70,9 +70,26 @@ class WrapTest(fixtures.TestBase): except sa_exceptions.DBAPIError as exc: eq_( str(exc), - "(test.base.test_except.OperationalError) " - "[SQL: 'this is a message'] (Background on this error at: " - "http://sqlalche.me/e/e3q8)", + "(test.base.test_except.OperationalError) \n" + "[SQL: this is a message]\n" + "(Background on this error at: http://sqlalche.me/e/e3q8)", + ) + + def test_tostring_with_newlines(self): + try: + raise sa_exceptions.DBAPIError.instance( + "this is a message\nthis is the next line\nthe last line", + None, + OperationalError(), + DatabaseError, + ) + except sa_exceptions.DBAPIError as exc: + eq_( + str(exc), + "(test.base.test_except.OperationalError) \n" + "[SQL: this is a message\nthis is the next line\n" + "the last line]\n" + "(Background on this error at: http://sqlalche.me/e/e3q8)", ) def test_statement_error_no_code(self): @@ -86,8 +103,8 @@ class WrapTest(fixtures.TestBase): except sa_exceptions.StatementError as err: eq_( str(err), - "(sqlalchemy.exc.InvalidRequestError) hello " - "[SQL: 'select * from table'] [parameters: [{'x': 1}]]", + "(sqlalchemy.exc.InvalidRequestError) hello\n" + "[SQL: select * from table]\n[parameters: [{'x': 1}]]", ) eq_(err.args, ("(sqlalchemy.exc.InvalidRequestError) hello",)) @@ -102,8 +119,9 @@ class WrapTest(fixtures.TestBase): except sa_exceptions.StatementError as err: eq_( str(err), - "(sqlalchemy.exc.InvalidRequestError) hello " - "[SQL: 'select * from table'] [parameters: [{'x': 1}]] " + "(sqlalchemy.exc.InvalidRequestError) hello\n" + "[SQL: select * from table]\n" + "[parameters: [{'x': 1}]]\n" "(Background on this error at: http://sqlalche.me/e/abcd)", ) eq_(err.args, ("(sqlalchemy.exc.InvalidRequestError) hello",)) @@ -114,7 +132,7 @@ class WrapTest(fixtures.TestBase): orig.args = [2006, "Test raise operational error"] eq_( str(orig), - "(2006, 'Test raise operational error') " + "(2006, 'Test raise operational error')\n" "(Background on this error at: http://sqlalche.me/e/dbapi)", ) @@ -125,7 +143,7 @@ class WrapTest(fixtures.TestBase): eq_( compat.text_type(orig), compat.u( - "méil (Background on this error at: " + "méil\n(Background on this error at: " "http://sqlalche.me/e/dbapi)" ), ) @@ -153,8 +171,9 @@ class WrapTest(fixtures.TestBase): ) except sa_exceptions.DBAPIError as exc: assert str(exc).startswith( - "(test.base.test_except.OperationalError) " - "[SQL: 'this is a message'] [parameters: {" + "(test.base.test_except.OperationalError) \n" + "[SQL: this is a message]\n" + "[parameters: {" ) def test_tostring_large_list(self): @@ -165,10 +184,10 @@ class WrapTest(fixtures.TestBase): OperationalError(), DatabaseError, ) - except sa_exceptions.DBAPIError as exc: - assert str(exc).startswith( - "(test.base.test_except.OperationalError) " - "[SQL: 'this is a message'] [parameters: " + except sa_exceptions.DBAPIError as ex: + assert str(ex).startswith( + "(test.base.test_except.OperationalError) \n" + "[SQL: this is a message]\n[parameters: " "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]]" ) @@ -194,11 +213,11 @@ class WrapTest(fixtures.TestBase): except sa_exceptions.DBAPIError as exc: eq_( str(exc), - "(test.base.test_except.OperationalError) sql error " - "[SQL: 'this is a message'] [parameters: [{1: 1}, " - "{1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: " - "1}, {1: 1}, {1: 1}]] (Background on this error at: " - "http://sqlalche.me/e/e3q8)", + "(test.base.test_except.OperationalError) sql error\n" + "[SQL: this is a message]\n" + "[parameters: [{1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}," + " {1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}]]\n" + "(Background on this error at: http://sqlalche.me/e/e3q8)", ) eq_( exc.args, @@ -226,11 +245,12 @@ class WrapTest(fixtures.TestBase): except sa_exceptions.DBAPIError as exc: eq_( str(exc), - "(test.base.test_except.OperationalError) " - "[SQL: 'this is a message'] [parameters: [{1: 1}, " + "(test.base.test_except.OperationalError) \n" + "[SQL: this is a message]\n" + "[parameters: [{1: 1}, " "{1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}, " "{1: 1}, {1: 1} ... displaying 10 of 11 total " - "bound parameter sets ... {1: 1}, {1: 1}]] " + "bound parameter sets ... {1: 1}, {1: 1}]]\n" "(Background on this error at: http://sqlalche.me/e/e3q8)", ) try: @@ -244,9 +264,10 @@ class WrapTest(fixtures.TestBase): except sa_exceptions.DBAPIError as exc: eq_( str(exc), - "(test.base.test_except.OperationalError) " - "[SQL: 'this is a message'] [parameters: [(1,), " - "(1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,)]] " + "(test.base.test_except.OperationalError) \n" + "[SQL: this is a message]\n" + "[parameters: [(1,), " + "(1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,)]]\n" "(Background on this error at: http://sqlalche.me/e/e3q8)", ) try: @@ -271,11 +292,12 @@ class WrapTest(fixtures.TestBase): except sa_exceptions.DBAPIError as exc: eq_( str(exc), - "(test.base.test_except.OperationalError) " - "[SQL: 'this is a message'] [parameters: [(1,), " + "(test.base.test_except.OperationalError) \n" + "[SQL: this is a message]\n" + "[parameters: [(1,), " "(1,), (1,), (1,), (1,), (1,), (1,), (1,) " "... displaying 10 of 11 total bound " - "parameter sets ... (1,), (1,)]] " + "parameter sets ... (1,), (1,)]]\n" "(Background on this error at: http://sqlalche.me/e/e3q8)", ) diff --git a/test/engine/test_deprecations.py b/test/engine/test_deprecations.py index 35226a097..29bda0ac2 100644 --- a/test/engine/test_deprecations.py +++ b/test/engine/test_deprecations.py @@ -1114,7 +1114,7 @@ class HandleErrorTest(fixtures.TestBase): with engine.connect() as conn: assert_raises_message( tsa.exc.StatementError, - r"\(.*SomeException\) " r"nope \[SQL\: u?'SELECT 1 ", + r"\(.*SomeException\) " r"nope\n\[SQL\: u?SELECT 1 ", conn.execute, select([1]).where(column("foo") == literal("bar", MyType())), ) diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py index ad9144a38..e18cdfad4 100644 --- a/test/engine/test_execute.py +++ b/test/engine/test_execute.py @@ -371,7 +371,7 @@ class ExecuteTest(fixtures.TestBase): def _go(conn): assert_raises_message( tsa.exc.StatementError, - r"\(.*.SomeException\) " r"nope \[SQL\: u?'SELECT 1 ", + r"\(.*.SomeException\) " r"nope\n\[SQL\: u?SELECT 1 ", conn.execute, select([1]).where(column("foo") == literal("bar", MyType())), ) @@ -410,12 +410,12 @@ class ExecuteTest(fixtures.TestBase): assert_raises_message( tsa.exc.StatementError, util.u( - "A value is required for bind parameter 'uname'" - r".*SELECT users.user_name AS .m\\xe9il." + "A value is required for bind parameter 'uname'\n" + r".*SELECT users.user_name AS .m\xe9il." ) if util.py2k else util.u( - "A value is required for bind parameter 'uname'" + "A value is required for bind parameter 'uname'\n" ".*SELECT users.user_name AS .méil." ), conn.execute, @@ -2184,7 +2184,7 @@ class HandleErrorTest(fixtures.TestBase): with engine.connect() as conn: assert_raises_message( tsa.exc.StatementError, - r"\(.*.SomeException\) " r"nope \[SQL\: u?'SELECT 1 ", + r"\(.*.SomeException\) " r"nope\n\[SQL\: u?SELECT 1 ", conn.execute, select([1]).where(column("foo") == literal("bar", MyType())), ) diff --git a/test/engine/test_logging.py b/test/engine/test_logging.py index 8190a3fcd..bd425c940 100644 --- a/test/engine/test_logging.py +++ b/test/engine/test_logging.py @@ -103,7 +103,7 @@ class LogParamsTest(fixtures.TestBase): exception = tsa.exc.IntegrityError("foo", {"x": "y"}, None) eq_regex( str(exception), - r"\(.*.NoneType\) None \[SQL: 'foo'\] \[parameters: {'x': 'y'}\]", + r"\(.*.NoneType\) None\n\[SQL: foo\]\n\[parameters: {'x': 'y'}\]", ) def test_exception_format_unexpected_parameter(self): @@ -112,7 +112,7 @@ class LogParamsTest(fixtures.TestBase): exception = tsa.exc.IntegrityError("foo", "bar", "bat") eq_regex( str(exception), - r"\(.*.str\) bat \[SQL: 'foo'\] \[parameters: 'bar'\]", + r"\(.*.str\) bat\n\[SQL: foo\]\n\[parameters: 'bar'\]", ) def test_exception_format_unexpected_member_parameter(self): @@ -121,7 +121,7 @@ class LogParamsTest(fixtures.TestBase): exception = tsa.exc.IntegrityError("foo", ["bar", "bat"], "hoho") eq_regex( str(exception), - r"\(.*.str\) hoho \[SQL: 'foo'\] \[parameters: \['bar', 'bat'\]\]", + r"\(.*.str\) hoho\n\[SQL: foo\]\n\[parameters: \['bar', 'bat'\]\]", ) def test_result_large_param(self): @@ -169,7 +169,7 @@ class LogParamsTest(fixtures.TestBase): def test_error_large_dict(self): assert_raises_message( tsa.exc.DBAPIError, - r".*'INSERT INTO nonexistent \(data\) values \(:data\)'\] " + r".*INSERT INTO nonexistent \(data\) values \(:data\)\]\n" r"\[parameters: " r"\[{'data': '0'}, {'data': '1'}, {'data': '2'}, " r"{'data': '3'}, {'data': '4'}, {'data': '5'}, " @@ -186,7 +186,7 @@ class LogParamsTest(fixtures.TestBase): assert_raises_message( tsa.exc.DBAPIError, r".*INSERT INTO nonexistent \(data\) values " - r"\(\?\)'\] \[parameters: \[\('0',\), \('1',\), \('2',\), " + r"\(\?\)\]\n\[parameters: \[\('0',\), \('1',\), \('2',\), " r"\('3',\), \('4',\), \('5',\), \('6',\), \('7',\) " r"... displaying " r"10 of 100 total bound parameter sets ... " diff --git a/test/orm/test_session.py b/test/orm/test_session.py index 2bc11398d..ad7ff2d35 100644 --- a/test/orm/test_session.py +++ b/test/orm/test_session.py @@ -1037,7 +1037,7 @@ class DeferredRelationshipExpressionTest(_fixtures.FixtureTest): assert_raises_message( sa.exc.StatementError, "Can't resolve value for column users.id on object " - ".User.*.; the object is detached and the value was expired ", + ".User.*.; the object is detached and the value was expired", q.one, ) diff --git a/test/sql/test_insert_exec.py b/test/sql/test_insert_exec.py index fafe7cc9b..7905dc4bc 100644 --- a/test/sql/test_insert_exec.py +++ b/test/sql/test_insert_exec.py @@ -60,8 +60,8 @@ class InsertExecTest(fixtures.TablesTest): exc.StatementError, r"\(sqlalchemy.exc.InvalidRequestError\) A value is required for " "bind parameter 'user_name', in " - "parameter group 2 " - r"\[SQL: u?'INSERT INTO users", + "parameter group 2\n" + r"\[SQL: u?INSERT INTO users", users.insert().execute, {"user_id": 7, "user_name": "jack"}, {"user_id": 8, "user_name": "ed"}, |
