You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The use of or operator calls the __bool__ function of the objects mapped to the self or cls keys. This causes problems when the object cannot be converted to bool which is unfortunately the case when using sqlalchemy, because it raises a TypeError for some of its classes (see here). The problem being that instead of the original DB error, the TypeError is propagated and the web exception renderer doesn't work for this case.
URL to code causing the issue
No response
MCVE
fromlitestarimportLitestar, getfromlitestar.contrib.sqlalchemy.baseimportBigIntBasefromlitestar.contrib.sqlalchemy.pluginsimport (
AsyncSessionConfig,
SQLAlchemyAsyncConfig,
SQLAlchemyInitPlugin,
)
fromsqlalchemy.ext.asyncioimportAsyncSessionfromsqlalchemy.ormimportMapped, mapped_columnclassName(BigIntBase):
name: Mapped[str] =mapped_column(unique=True)
@get("/")asyncdefadd_row(db_session: AsyncSession) ->dict:
asyncwithdb_session.begin():
new_name=Name(name="taken")
db_session.add(new_name)
return {"status": "ok"}
sqlalchemy_config=SQLAlchemyAsyncConfig(
connection_string="sqlite+aiosqlite:///test.sqlite3",
session_config=AsyncSessionConfig(expire_on_commit=False),
)
sqlalchemy_plugin=SQLAlchemyInitPlugin(config=sqlalchemy_config)
asyncdefon_startup() ->None:
"""Initializes the database."""asyncwithsqlalchemy_config.get_engine().begin() asconn:
awaitconn.run_sync(BigIntBase.metadata.create_all)
app=Litestar(
route_handlers=[add_row], plugins=[sqlalchemy_plugin], on_startup=[on_startup]
)
# Run "get /" twice - first call creates the entry, second one causes the error.
Steps to reproduce
1. Run the MCVE app (requires `aiosqlite` to be installed) with `--debug`
2. Navigate to "/"for the first time which creates the db row
3. Navigate to "/"for the second time to cause an IntegrityError
4. A `TypeError` is raised and propagated instead of the original DB error
5. The web debug exception renderer doesn't work
Screenshots
No response
Logs
[SQL: INSERT INTO name (name) VALUES (?)]
[parameters: ('taken',)]
(Background on this error at: https://sqlalche.me/e/20/gkpj)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 191, in __call__
await self.app(scope, receive, send)
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 205, in __call__
await self.handle_request_exception(
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 234, in handle_request_exception
response = exception_handler(request, exc)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 270, in default_http_exception_handler
return create_debug_response(request=request, exc=exc)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 184, in create_debug_response
content: Any = create_html_response_content(exc=exc, request=request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 137, in create_html_response_content
exception_data: list[str] = [create_exception_html(exc, line_limit)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 122, in create_exception_html
result = [create_frame_html(frame=frame, collapsed=idx > 0) foridx, framein enumerate(reversed(frames))]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 122, in<listcomp>
result = [create_frame_html(frame=frame, collapsed=idx > 0) foridx, framein enumerate(reversed(frames))]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 104, in create_frame_html
"symbol_name": escape(get_symbol_name(frame)),
^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 51, in get_symbol_name
instance_or_cls = locals_dict.get("self") or locals_dict.get("cls")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/sqlalchemy/sql/elements.py", line 749, in __bool__
raise TypeError("Boolean value of this clause is not defined")
TypeError: Boolean value of this clause is not defined
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 191, in __call__
await self.app(scope, receive, send)
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/_asgi/asgi_router.py", line 84, in __call__
await asgi_app(scope, receive, send)
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 205, in __call__
await self.handle_request_exception(
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 234, in handle_request_exception
response = exception_handler(request, exc)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 270, in default_http_exception_handler
return create_debug_response(request=request, exc=exc)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 184, in create_debug_response
content: Any = create_html_response_content(exc=exc, request=request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 137, in create_html_response_content
exception_data: list[str] = [create_exception_html(exc, line_limit)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 122, in create_exception_html
result = [create_frame_html(frame=frame, collapsed=idx > 0) foridx, framein enumerate(reversed(frames))]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 122, in<listcomp>
result = [create_frame_html(frame=frame, collapsed=idx > 0) foridx, framein enumerate(reversed(frames))]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 104, in create_frame_html
"symbol_name": escape(get_symbol_name(frame)),
^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 51, in get_symbol_name
instance_or_cls = locals_dict.get("self") or locals_dict.get("cls")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/sqlalchemy/sql/elements.py", line 749, in __bool__
raise TypeError("Boolean value of this clause is not defined")
TypeError: Boolean value of this clause is not defined
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 426, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 84, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/app.py", line 517, in __call__
await self.asgi_handler(scope, receive, self._wrap_send(send=send, scope=scope)) # type: ignore[arg-type]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 205, in __call__
await self.handle_request_exception(
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 234, in handle_request_exception
response = exception_handler(request, exc)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 270, in default_http_exception_handler
return create_debug_response(request=request, exc=exc)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 184, in create_debug_response
content: Any = create_html_response_content(exc=exc, request=request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 137, in create_html_response_content
exception_data: list[str] = [create_exception_html(exc, line_limit)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 122, in create_exception_html
result = [create_frame_html(frame=frame, collapsed=idx > 0) foridx, framein enumerate(reversed(frames))]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 122, in<listcomp>
result = [create_frame_html(frame=frame, collapsed=idx > 0) foridx, framein enumerate(reversed(frames))]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 104, in create_frame_html
"symbol_name": escape(get_symbol_name(frame)),
^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/_debug_response.py", line 51, in get_symbol_name
instance_or_cls = locals_dict.get("self") or locals_dict.get("cls")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/geeshta/prog/litestar/bugs/.venv/lib/python3.11/site-packages/sqlalchemy/sql/elements.py", line 749, in __bool__
raise TypeError("Boolean value of this clause is not defined")
TypeError: Boolean value of this clause is not defined
INFO: 127.0.0.1:48748 - "GET / HTTP/1.1" 500 Internal Server Error
Litestar Version
2.1.1
Platform
Linux
Mac
Windows
Other (Please specify in the description above)
Funding
If you would like to see an issue prioritized, make a pledge towards it!
We receive the pledge once the issue is completed & verified
The text was updated successfully, but these errors were encountered:
Description
The function
litestar.middleware.exceptions._debug_response.get_symbol_name
on line 51:The use of
or
operator calls the__bool__
function of the objects mapped to theself
orcls
keys. This causes problems when the object cannot be converted to bool which is unfortunately the case when using sqlalchemy, because it raises aTypeError
for some of its classes (see here). The problem being that instead of the original DB error, the TypeError is propagated and the web exception renderer doesn't work for this case.URL to code causing the issue
No response
MCVE
Steps to reproduce
Screenshots
No response
Logs
Litestar Version
2.1.1
Platform
Funding
The text was updated successfully, but these errors were encountered: