A pydantic validation error raised in a handler causes an error in rich logging output. If the error raised in the handler isn't a pydantic validation error (e.g., RuntimeError, ValueError, etc) then it doesn't seem to be an issue. If rich isn't installed, there isn't an issue either.
To reproduce, install starlite-saqlalchemy and rich and create .env and main.py as per below:
# main.py
from pydantic import BaseModel
from starlite import Starlite, get
from starlite_saqlalchemy import ConfigureApp, PluginConfig, scripts
class Model(BaseModel):
a: float
@get("/test")
async def test() -> Model:
return Model(a="string")
app = Starlite(route_handlers=[test], on_app_init=[ConfigureApp(PluginConfig(do_worker=False))])
if __name__ == "__main__":
scripts.run_app()
The repro explicitly causes a pydantic validation error in the handler which causes:
--- Logging error ---
Traceback (most recent call last):
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/middleware/exceptions/middleware.py", line 47, in __call__
await self.app(scope, receive, send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/routes/http.py", line 79, in handle
response = await self._get_response_for_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/routes/http.py", line 131, in _get_response_for_request
response = await self._call_handler_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/routes/http.py", line 160, in _call_handler_function
response_data, cleanup_group = await self._get_response_data(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/routes/http.py", line 218, in _get_response_data
data = await route_handler.fn.value(**parsed_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/main.py", line 13, in test
return Model(a="string")
^^^^^^^^^^^^^^^^^
File "pydantic/main.py", line 342, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for Model
a
value is not a valid float (type=type_error.float)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/middleware/exceptions/middleware.py", line 47, in __call__
await self.app(scope, receive, send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite_saqlalchemy/log/controller.py", line 75, in middleware
await app(scope, receive, send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/middleware/base.py", line 137, in wrapped_call
await original__call__(self, scope, receive, send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/middleware/compression.py", line 138, in __call__
await self.app(
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/middleware/exceptions/middleware.py", line 58, in __call__
await response(scope=scope, receive=receive, send=send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite_saqlalchemy/log/controller.py", line 151, in __call__
await LOGGER.aerror("Error in logging before-send handler!", exc_info=exc)
File "/home/peter/.pyenv/versions/3.11.1/lib/python3.11/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/structlog/_log_levels.py", line 168, in <lambda>
lambda: ctx.run(
^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/structlog/_log_levels.py", line 169, in <lambda>
lambda: self._proxy_to_logger(name, event, **kw)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/structlog/_base.py", line 205, in _proxy_to_logger
args, kw = self._process_event(method_name, event, event_kw)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/structlog/_base.py", line 162, in _process_event
event_dict = proc(self._logger, method_name, event_dict)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/structlog/dev.py", line 424, in __call__
self._exception_formatter(sio, exc_info)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/structlog/dev.py", line 187, in rich_traceback
Traceback.from_exception(*exc_info, show_locals=True)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/traceback.py", line 335, in from_exception
rich_traceback = cls.extract(
^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/traceback.py", line 405, in extract
exc_type=safe_str(exc_type.__name__),
^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '__name__'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/middleware/exceptions/middleware.py", line 47, in __call__
await self.app(scope, receive, send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/asgi/asgi_router.py", line 80, in __call__
await asgi_app(scope, receive, send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/middleware/exceptions/middleware.py", line 58, in __call__
await response(scope=scope, receive=receive, send=send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/response/base.py", line 381, in __call__
await self.start_response(send=send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/response/base.py", line 352, in start_response
await send(event)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/app.py", line 700, in wrapped_send
await send(message)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py", line 501, in send
raise RuntimeError(msg % message_type)
RuntimeError: Expected ASGI message 'http.response.body', but got 'http.response.start'.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py", line 407, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/app.py", line 422, in __call__
await self.asgi_handler(scope, receive, self._wrap_send(send=send, scope=scope)) # type: ignore[arg-type]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/middleware/exceptions/middleware.py", line 58, in __call__
await response(scope=scope, receive=receive, send=send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/response/base.py", line 381, in __call__
await self.start_response(send=send)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/response/base.py", line 352, in start_response
await send(event)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/starlite/app.py", line 700, in wrapped_send
await send(message)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py", line 501, in send
raise RuntimeError(msg % message_type)
RuntimeError: Expected ASGI message 'http.response.body', but got 'http.response.start'.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/syntax.py", line 497, in tokens_to_spans
_token_type, token = next(tokens)
^^^^^^^^^^^^
StopIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/peter/.pyenv/versions/3.11.1/lib/python3.11/logging/handlers.py", line 1498, in emit
self.enqueue(self.prepare(record))
^^^^^^^^^^^^^^^^^^^^
File "/home/peter/.pyenv/versions/3.11.1/lib/python3.11/logging/handlers.py", line 1480, in prepare
msg = self.format(record)
^^^^^^^^^^^^^^^^^^^
File "/home/peter/.pyenv/versions/3.11.1/lib/python3.11/logging/__init__.py", line 953, in format
return fmt.format(record)
^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/structlog/stdlib.py", line 963, in format
ed = p(logger, meth_name, ed)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/structlog/dev.py", line 424, in __call__
self._exception_formatter(sio, exc_info)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/structlog/dev.py", line 186, in rich_traceback
Console(file=sio, color_system="truecolor").print(
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/console.py", line 1694, in print
extend(render(renderable, render_options))
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/console.py", line 1330, in render
yield from self.render(render_output, _options)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/console.py", line 1326, in render
for render_output in iter_render:
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/constrain.py", line 29, in __rich_console__
yield from console.render(self.renderable, child_options)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/console.py", line 1326, in render
for render_output in iter_render:
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/panel.py", line 220, in __rich_console__
lines = console.render_lines(renderable, child_options, style=style)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/console.py", line 1366, in render_lines
lines = list(
^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/segment.py", line 292, in split_and_crop_lines
for segment in segments:
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/console.py", line 1326, in render
for render_output in iter_render:
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/padding.py", line 97, in __rich_console__
lines = console.render_lines(
^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/console.py", line 1366, in render_lines
lines = list(
^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/segment.py", line 292, in split_and_crop_lines
for segment in segments:
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/console.py", line 1330, in render
yield from self.render(render_output, _options)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/console.py", line 1326, in render
for render_output in iter_render:
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/syntax.py", line 609, in __rich_console__
segments = Segments(self._get_syntax(console, options))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/segment.py", line 668, in __init__
self.segments = list(segments)
^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/syntax.py", line 637, in _get_syntax
text = self.highlight(processed_code, self.line_range)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/syntax.py", line 509, in highlight
text.append_tokens(tokens_to_spans())
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/rich/text.py", line 995, in append_tokens
for content, style in tokens:
RuntimeError: generator raised StopIteration
Call stack:
File "<string>", line 1, in <module>
File "/home/peter/.pyenv/versions/3.11.1/lib/python3.11/multiprocessing/spawn.py", line 120, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "/home/peter/.pyenv/versions/3.11.1/lib/python3.11/multiprocessing/spawn.py", line 133, in _main
return self._bootstrap(parent_sentinel)
File "/home/peter/.pyenv/versions/3.11.1/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap
self.run()
File "/home/peter/.pyenv/versions/3.11.1/lib/python3.11/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/uvicorn/_subprocess.py", line 76, in subprocess_started
target(sockets=sockets)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/uvicorn/server.py", line 60, in run
return asyncio.run(self.serve(sockets=sockets))
File "/home/peter/.pyenv/versions/3.11.1/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
File "/home/peter/.pyenv/versions/3.11.1/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
File "/home/peter/PycharmProjects/rich-error-repro/.venv/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py", line 412, in run_asgi
self.logger.error(msg, exc_info=exc)
Message: 'Exception in ASGI application\n'
Arguments: ()
A pydantic validation error raised in a handler causes an error in
rich
logging output. If the error raised in the handler isn't a pydantic validation error (e.g., RuntimeError, ValueError, etc) then it doesn't seem to be an issue. If rich isn't installed, there isn't an issue either.To reproduce, install
starlite-saqlalchemy
andrich
and create.env
andmain.py
as per below:The repro explicitly causes a pydantic validation error in the handler which causes: