summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2021-01-23 15:33:50 +0000
committerGerrit Code Review <gerrit@bbpush.zzzcomputing.com>2021-01-23 15:33:50 +0000
commitfd3ca828f05198068eaf89c1f37f63fecad72a55 (patch)
treed3e5b98fbd09ab9772b9e75b0e23b31de18a8c35
parentb290352ae7980d0263310c167da33e26be83b16b (diff)
parentbb846d1650423ce8013feb93b3c8837b4c5498a0 (diff)
downloadsqlalchemy-fd3ca828f05198068eaf89c1f37f63fecad72a55.tar.gz
Merge "Improve error message when await_ call errors"
-rw-r--r--doc/build/errors.rst18
-rw-r--r--lib/sqlalchemy/exc.py9
-rw-r--r--lib/sqlalchemy/util/_concurrency_py3k.py10
-rw-r--r--test/base/test_concurrency_py3k.py4
4 files changed, 34 insertions, 7 deletions
diff --git a/doc/build/errors.rst b/doc/build/errors.rst
index 67a8a29b0..7d767a711 100644
--- a/doc/build/errors.rst
+++ b/doc/build/errors.rst
@@ -1130,7 +1130,23 @@ with a non compatible :term:`DBAPI`.
.. seealso::
- :ref:`asyncio extension <asyncio_toplevel>`
+ :ref:`asyncio_toplevel`
+
+.. _error_xd2s:
+
+MissingGreenlet
+---------------
+
+A call to the async :term:`DBAPI` was initiated outside the greenlet spawn context
+usually setup by the SQLAlchemy AsyncIO proxy classes.
+Usually this error happens when an IO was attempted in an unexpected
+place, without using the provided async api.
+When using the ORM this may be due to a lazy loading attempt, which
+is unsupported when using SQLAlchemy with AsyncIO dialects.
+
+.. seealso::
+
+ :ref:`_session_run_sync`
Core Exception Classes
diff --git a/lib/sqlalchemy/exc.py b/lib/sqlalchemy/exc.py
index 08b1bb060..289b8dfab 100644
--- a/lib/sqlalchemy/exc.py
+++ b/lib/sqlalchemy/exc.py
@@ -294,6 +294,15 @@ class AwaitRequired(InvalidRequestError):
code = "xd1r"
+class MissingGreenlet(InvalidRequestError):
+ r"""Error raised by the async greenlet await\_ if called while not inside
+ the greenlet spawn context.
+
+ """
+
+ code = "xd2s"
+
+
class NoReferencedTableError(NoReferenceError):
"""Raised by ``ForeignKey`` when the referred ``Table`` cannot be
located.
diff --git a/lib/sqlalchemy/util/_concurrency_py3k.py b/lib/sqlalchemy/util/_concurrency_py3k.py
index 663d3e0f4..8edd057ef 100644
--- a/lib/sqlalchemy/util/_concurrency_py3k.py
+++ b/lib/sqlalchemy/util/_concurrency_py3k.py
@@ -44,8 +44,9 @@ def await_only(awaitable: Coroutine) -> Any:
# this is called in the context greenlet while running fn
current = greenlet.getcurrent()
if not isinstance(current, _AsyncIoGreenlet):
- raise exc.InvalidRequestError(
- "greenlet_spawn has not been called; can't call await_() here."
+ raise exc.MissingGreenlet(
+ "greenlet_spawn has not been called; can't call await_() here. "
+ "Was IO attempted in an unexpected place?"
)
# returns the control to the driver greenlet passing it
@@ -69,9 +70,10 @@ def await_fallback(awaitable: Coroutine) -> Any:
if not isinstance(current, _AsyncIoGreenlet):
loop = asyncio.get_event_loop()
if loop.is_running():
- raise exc.InvalidRequestError(
+ raise exc.MissingGreenlet(
"greenlet_spawn has not been called and asyncio event "
- "loop is already running; can't call await_() here."
+ "loop is already running; can't call await_() here. "
+ "Was IO attempted in an unexpected place?"
)
return loop.run_until_complete(awaitable)
diff --git a/test/base/test_concurrency_py3k.py b/test/base/test_concurrency_py3k.py
index 8eabece92..1492bc186 100644
--- a/test/base/test_concurrency_py3k.py
+++ b/test/base/test_concurrency_py3k.py
@@ -63,7 +63,7 @@ class TestAsyncioCompat(fixtures.TestBase):
async def test_await_only_no_greenlet(self):
to_await = run1()
with expect_raises_message(
- exc.InvalidRequestError,
+ exc.MissingGreenlet,
r"greenlet_spawn has not been called; can't call await_\(\) here.",
):
await_only(to_await)
@@ -86,7 +86,7 @@ class TestAsyncioCompat(fixtures.TestBase):
await_fallback(inner_await())
with expect_raises_message(
- exc.InvalidRequestError,
+ exc.MissingGreenlet,
"greenlet_spawn has not been called and asyncio event loop",
):
await greenlet_spawn(go)