Environment
Python 3.14.4 on Macos,
1.0.0rc1 + starlette 0.46.2 (as extra)
Bug Description
Hi, I'm trying FastOpenAPI for a poc and to return in my first love language 😅
when an unhandled exception in raised in FastOpenAPI's routers the behavior of errors handling differ from default/builtin, may lead to difficulties to identifies root cause of 500 without wrapping the whole handler code in try + log + re raise
pure starlette => print the stacktrace to stderr
with FastOpenApi => only access log show the 500 status code
I digged a bit with starlette but I believe all others frameworks are affected, it's not related to the asgi server as uvicorn and granian show the same issue, aiohttp too (however I did not check if aiohttp print traceback by default)
was able to isolate the cause to BaseAdapter.handle_request_async that eat the exception to build http error
then i'm wondering if it's not possible to have generic error handling regardless of the framework, it could just be a callable attached to the router
I'm open to contribute and make a PR I just want to ensure this feature would be suitable and not too out of scope of original lib goal
Steps to Reproduce
import logging
from fastopenapi import Response
import inspect
from fastopenapi.routers import StarletteRouter
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
async def root(_request):
1 / 0
return JSONResponse(content={"hello": "world"})
app = Starlette(
debug=True,
routes=[
Route("/1", root),
],
)
router = StarletteRouter(app=app)
@router.get("/2")
async def root_fastopenapi():
1 / 0
return JSONResponse({"hello": "world"})
async def handle_request_async(endpoint, env):
"""Handle asynchronous request"""
try:
request_data = await router.extractor_async_cls.extract_request_data(env)
kwargs = await router.req_param_resolver_cls.resolve_async(
endpoint, request_data
)
if inspect.iscoroutinefunction(endpoint):
result = await endpoint(**kwargs)
else:
result = endpoint(**kwargs)
route_meta = endpoint.__route_meta__
response_model = route_meta.get("response_model")
if response_model:
result = router._validate_response(result, response_model)
if router.is_framework_response(result):
return result
response = router.response_builder_cls.build(result, route_meta)
if route_meta.get("status_code") == 204:
response.content = None
return router.build_framework_response(response)
except Exception as e:
logging.exception(e, exc_info=True) # <- e is used to build api response but not used at all for debugging purpose
return router.build_framework_response(
Response(
content="ugly monkeypatch",
status_code=500,
)
)
router.handle_request_async = handle_request_async
GET /1 => logged error and return 500 to client
GET /2 => return 500 to client but silent underlying error
Logs or Tracebacks
Contact
@ mention me on github
Environment
Python 3.14.4 on Macos,
1.0.0rc1 + starlette 0.46.2 (as extra)
Bug Description
Hi, I'm trying FastOpenAPI for a poc and to return in my first love language 😅
when an unhandled exception in raised in FastOpenAPI's routers the behavior of errors handling differ from default/builtin, may lead to difficulties to identifies root cause of 500 without wrapping the whole handler code in try + log + re raise
pure starlette => print the stacktrace to stderr
with FastOpenApi => only access log show the 500 status code
I digged a bit with starlette but I believe all others frameworks are affected, it's not related to the asgi server as uvicorn and granian show the same issue, aiohttp too (however I did not check if aiohttp print traceback by default)
was able to isolate the cause to BaseAdapter.handle_request_async that eat the exception to build http error
then i'm wondering if it's not possible to have generic error handling regardless of the framework, it could just be a callable attached to the router
I'm open to contribute and make a PR I just want to ensure this feature would be suitable and not too out of scope of original lib goal
Steps to Reproduce
GET /1=> logged error and return 500 to clientGET /2=> return 500 to client but silent underlying errorLogs or Tracebacks
Contact
@ mention me on github