File tree Expand file tree Collapse file tree 4 files changed +34
-7
lines changed Expand file tree Collapse file tree 4 files changed +34
-7
lines changed Original file line number Diff line number Diff line change @@ -1130,7 +1130,23 @@ with a non compatible :term:`DBAPI`.
1130
1130
1131
1131
.. seealso ::
1132
1132
1133
- :ref: `asyncio extension <asyncio_toplevel >`
1133
+ :ref: `asyncio_toplevel `
1134
+
1135
+ .. _error_xd2s :
1136
+
1137
+ MissingGreenlet
1138
+ ---------------
1139
+
1140
+ A call to the async :term: `DBAPI ` was initiated outside the greenlet spawn context
1141
+ usually setup by the SQLAlchemy AsyncIO proxy classes.
1142
+ Usually this error happens when an IO was attempted in an unexpected
1143
+ place, without using the provided async api.
1144
+ When using the ORM this may be due to a lazy loading attempt, which
1145
+ is unsupported when using SQLAlchemy with AsyncIO dialects.
1146
+
1147
+ .. seealso ::
1148
+
1149
+ :ref: `_session_run_sync `
1134
1150
1135
1151
1136
1152
Core Exception Classes
Original file line number Diff line number Diff line change @@ -294,6 +294,15 @@ class AwaitRequired(InvalidRequestError):
294
294
code = "xd1r"
295
295
296
296
297
+ class MissingGreenlet (InvalidRequestError ):
298
+ r"""Error raised by the async greenlet await\_ if called while not inside
299
+ the greenlet spawn context.
300
+
301
+ """
302
+
303
+ code = "xd2s"
304
+
305
+
297
306
class NoReferencedTableError (NoReferenceError ):
298
307
"""Raised by ``ForeignKey`` when the referred ``Table`` cannot be
299
308
located.
Original file line number Diff line number Diff line change @@ -44,8 +44,9 @@ def await_only(awaitable: Coroutine) -> Any:
44
44
# this is called in the context greenlet while running fn
45
45
current = greenlet .getcurrent ()
46
46
if not isinstance (current , _AsyncIoGreenlet ):
47
- raise exc .InvalidRequestError (
48
- "greenlet_spawn has not been called; can't call await_() here."
47
+ raise exc .MissingGreenlet (
48
+ "greenlet_spawn has not been called; can't call await_() here. "
49
+ "Was IO attempted in an unexpected place?"
49
50
)
50
51
51
52
# returns the control to the driver greenlet passing it
@@ -69,9 +70,10 @@ def await_fallback(awaitable: Coroutine) -> Any:
69
70
if not isinstance (current , _AsyncIoGreenlet ):
70
71
loop = asyncio .get_event_loop ()
71
72
if loop .is_running ():
72
- raise exc .InvalidRequestError (
73
+ raise exc .MissingGreenlet (
73
74
"greenlet_spawn has not been called and asyncio event "
74
- "loop is already running; can't call await_() here."
75
+ "loop is already running; can't call await_() here. "
76
+ "Was IO attempted in an unexpected place?"
75
77
)
76
78
return loop .run_until_complete (awaitable )
77
79
Original file line number Diff line number Diff line change @@ -63,7 +63,7 @@ def test_await_fallback_no_greenlet(self):
63
63
async def test_await_only_no_greenlet (self ):
64
64
to_await = run1 ()
65
65
with expect_raises_message (
66
- exc .InvalidRequestError ,
66
+ exc .MissingGreenlet ,
67
67
r"greenlet_spawn has not been called; can't call await_\(\) here." ,
68
68
):
69
69
await_only (to_await )
@@ -86,7 +86,7 @@ def go():
86
86
await_fallback (inner_await ())
87
87
88
88
with expect_raises_message (
89
- exc .InvalidRequestError ,
89
+ exc .MissingGreenlet ,
90
90
"greenlet_spawn has not been called and asyncio event loop" ,
91
91
):
92
92
await greenlet_spawn (go )
You can’t perform that action at this time.
0 commit comments