-
-
Notifications
You must be signed in to change notification settings - Fork 769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stack trace not available to logger in v3 error handler function #2019
Comments
By using the debugger I was able to figure out that the Python logging function
When connexion v2 handles an exception, that function returns something useful:
But under connexion v3, that function returns None:
Restating the obvious, the doc on
Please comment, how can connexion pass more context to my little exception handler? For example, I think in |
Finally spotted this in the doc:
So if I define my exception handler as |
I'm sure it will surprise none of the maintainers lol that this works just fine, the logger shows a full stack trace:
Happy to have a solution, it raises many more questions:
|
Document that a regular function has no access to the exception stack traceback Fixes spec-first#2019
Document that a regular function has no access to the exception stack traceback Extend the `add_error_handler` function's Pydoc similarly Fixes spec-first#2019
Thanks for the report @chrisinmtown. I would propose a different fix though. Seems like we're losing the stacktrace info since we're running the sync function in a threadpool, which is probably not needed for error handlers. So I would just call the error handler directly instead. |
Thanks for the reply @RobbeSneyders. Maybe you are telling me that the error handler is called from an async context already, so it doesn't really need to be declared I think the project will def need some doc to help people migrate to version 3.1.0 and beyond. Please let me know what you decide, I will adjust or drop PR #2021 |
The error handler is being called from an connexion/connexion/middleware/exceptions.py Lines 36 to 39 in 1844a2f
This is done to prevent the handler from blocking the event loop. The downside is that it loses the stack trace information. Now I'm wondering if we really need to call exception handlers in a threadpool, since I assume they usually won't do a lot of io. We could just call the handler directly, which would preserve the stack trace for sync error handlers. |
Looking at Starlette and FastAPI, they seem to have the same issue. It's probably safest to keep running the sync handlers in a threadpool, since people might be logging errors. So I would indeed go for a docs update, but I would not blindly recommend |
Document that a sync function is run in a threadpool and has no access to the exception stack traceback, but an async function does. Extend the `add_error_handler` function's Pydoc similarly Fixes spec-first#2019
Document that a sync function is run in a threadpool and has no access to the exception stack traceback, but an async function does. Extend the `add_error_handler` function's Pydoc similarly Fixes spec-first#2019
I revised my PR, it no longer blindly recommends |
Document that a sync function is run in a threadpool and has no access to the exception stack traceback, but an async function does. Extend the `add_error_handler` function's Pydoc similarly Fixes spec-first#2019
Happy new year @RobbeSneyders I think I addressed all your comments in this revised PR, would you please review? |
Description
Please help me convince the V3 error-handler function to log a complete stack trace when an exception is raised. As far as I can tell, the stack trace is not available, and that change is a regression from V2. A stack trace is critical for discovering what really failed. For example, if some function raises
KeyError('1')
the message is just1
and that's not really helpful if operations brings that back from a production error!Expected behaviour
In a function hooked via the
add_error_handler
function, callinglogger.exception
will log a full stack trace.Actual behaviour
In a function hooked via the
add_error_handler
function, callinglogger.exception
yields only a string version of the exception, same as callinglogger.error
; no stack trace is logged.Steps to reproduce
Start with the directory https://github.com/spec-first/connexion/tree/main/examples/helloworld and add the python files with the content below.
Here's
hello_v2.py
for Connexion V2 which works as I expect, callinglogger.exception
prints a stack trace on exception:Here's
hello_v3.py
for Connexion V3 which somehow does not preserve the stack trace (?)Next you'll have to create two virtual environments:
Now you can run the v2 version, which yields a stack trace:
source venv-v2/bin/activate
ln -s hello_v2.py hello.py
(the spec files point to modulehello
)python3 hello.py
Here's the log output I get from v2:
Finally you can run the v3 version:
source venv-v3/bin/activate
ln -s hello_v3.py hello.py
(again this avoids changing the operation ID in the spec files)python3 hello.py
Here's the log output I get from v3:
I am pretty sure that the line with
NoneType: None
shown after my ERROR log output and before the access-log entry is from thelogger._log
function when it tries to discover & print a stack trace.For what it's worth, if no error handler function is hooked, I get a full stack trace on the console! I'll show it here just for completeness.
Additional info:
Python 3.12
Connexion 3.1.0
The text was updated successfully, but these errors were encountered: