fastapi: 第十二章:用loguru记录异常
一,记录捕捉到的异常
代码:
@router.get("/all")
def get_all_products():
try:
a = 0
b = 100 / a
print(b)
products = [{"id": 1, "name": "手机"}, {"id": 2, "name": "电脑"}]
return success(data=products)
except Exception as e:
logger.error("遇到了一个异常:{}", e)
return fail(code=501,msg=f"获取产品时遇到异常:{e}")
测试效果:

查看日志:
2026-05-24 12:29:04.479 | ERROR | app.api.products:get_all_products:18 - 遇到了一个异常:division by zero
二,记录全局异常
1,发生异常时记录数据:
说明:loguru的exception方法能记录详细的异常堆栈
# 4. 捕获系统未知异常 (如: 代码崩溃、数据库连接断开 500)
@app.exception_handler(Exception)
async def all_exception_handler(request: Request, exc: Exception):
# 注意:生产环境应将 exc 记录到日志系统(如 loguru)
logger.exception(f"服务器内部崩溃 -> 路由: {request.url.path} | 方法: {request.method}")
content = BaseResponse(code=500, msg="服务器内部错误,请稍后再试", data=None).model_dump()
return JSONResponse(status_code=500, content=content)
2,查看日志内容:
2026-05-24 13:11:16.621 | ERROR | app.core.exceptions:all_exception_handler:38 - 服务器内部崩溃 -> 路由: /products/all | 方法: GET
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/soft/python3.10.19/lib/python3.10/multiprocessing/spawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
│ │ └ 4
│ └ 7
└ <function _main at 0x7305fa0bbb50>
File "/usr/local/soft/python3.10.19/lib/python3.10/multiprocessing/spawn.py", line 129, in _main
return self._bootstrap(parent_sentinel)
│ │ └ 4
│ └ <function BaseProcess._bootstrap at 0x7305fa236200>
└ <SpawnProcess name='SpawnProcess-11' parent=4179 started>
File "/usr/local/soft/python3.10.19/lib/python3.10/multiprocessing/process.py", line 314, in _bootstrap
self.run()
│ └ <function BaseProcess.run at 0x7305fa235870>
└ <SpawnProcess name='SpawnProcess-11' parent=4179 started>
File "/usr/local/soft/python3.10.19/lib/python3.10/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
│ │ │ │ │ └ {'config': <uvicorn.config.Config object at 0x7305fa0cf220>, 'target': <bound method Server.run of <uvicorn.server.Server obj...
│ │ │ │ └ <SpawnProcess name='SpawnProcess-11' parent=4179 started>
│ │ │ └ ()
│ │ └ <SpawnProcess name='SpawnProcess-11' parent=4179 started>
│ └ <function subprocess_started at 0x7305f94c6e60>
└ <SpawnProcess name='SpawnProcess-11' parent=4179 started>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/uvicorn/_subprocess.py", line 80, in subprocess_started
target(sockets=sockets)
│ └ [<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8000)>]
└ <bound method Server.run of <uvicorn.server.Server object at 0x7305fa0cf280>>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/uvicorn/server.py", line 75, in run
return asyncio_run(self.serve(sockets=sockets), loop_factory=self.config.get_loop_factory())
│ │ │ │ │ │ └ <function Config.get_loop_factory at 0x7305f96bfa30>
│ │ │ │ │ └ <uvicorn.config.Config object at 0x7305fa0cf220>
│ │ │ │ └ <uvicorn.server.Server object at 0x7305fa0cf280>
│ │ │ └ [<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8000)>]
│ │ └ <function Server.serve at 0x7305f94c5ea0>
│ └ <uvicorn.server.Server object at 0x7305fa0cf280>
└ <function asyncio_run at 0x7305f966e950>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/uvicorn/_compat.py", line 60, in asyncio_run
return loop.run_until_complete(main)
│ │ └ <coroutine object Server.serve at 0x7305f9489c40>
│ └ <function BaseEventLoop.run_until_complete at 0x7305f986d630>
└ <_UnixSelectorEventLoop running=True closed=False debug=False>
File "/usr/local/soft/python3.10.19/lib/python3.10/asyncio/base_events.py", line 636, in run_until_complete
self.run_forever()
│ └ <function BaseEventLoop.run_forever at 0x7305f986d5a0>
└ <_UnixSelectorEventLoop running=True closed=False debug=False>
File "/usr/local/soft/python3.10.19/lib/python3.10/asyncio/base_events.py", line 603, in run_forever
self._run_once()
│ └ <function BaseEventLoop._run_once at 0x7305f986f0a0>
└ <_UnixSelectorEventLoop running=True closed=False debug=False>
File "/usr/local/soft/python3.10.19/lib/python3.10/asyncio/base_events.py", line 1909, in _run_once
handle._run()
│ └ <function Handle._run at 0x7305f99ce440>
└ <Handle Task.task_wakeup(<Future finis...ion by zero')>)>
File "/usr/local/soft/python3.10.19/lib/python3.10/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
│ │ │ │ │ └ <member '_args' of 'Handle' objects>
│ │ │ │ └ <Handle Task.task_wakeup(<Future finis...ion by zero')>)>
│ │ │ └ <member '_callback' of 'Handle' objects>
│ │ └ <Handle Task.task_wakeup(<Future finis...ion by zero')>)>
│ └ <member '_context' of 'Handle' objects>
└ <Handle Task.task_wakeup(<Future finis...ion by zero')>)>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 415, in run_asgi
result = await app( # type: ignore[func-returns-value]
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x7305f95099c0>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 56, in __call__
return await self.app(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <fastapi.applications.FastAPI object at 0x7305f9509b70>
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x7305f95099c0>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/fastapi/applications.py", line 1159, in __call__
await super().__call__(scope, receive, send)
│ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
└ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/applications.py", line 90, in __call__
await self.middleware_stack(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <starlette.middleware.errors.ServerErrorMiddleware object at 0x7305f7c6ca00>
└ <fastapi.applications.FastAPI object at 0x7305f9509b70>
> File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 164, in __call__
await self.app(scope, receive, _send)
│ │ │ │ └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x7305f7c7c5e0>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <starlette.middleware.exceptions.ExceptionMiddleware object at 0x7305f7c6ca30>
└ <starlette.middleware.errors.ServerErrorMiddleware object at 0x7305f7c6ca00>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 63, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
│ │ │ │ │ │ └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x7305f7c7c5e0>
│ │ │ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ │ │ └ <starlette.requests.Request object at 0x7305f7c6c520>
│ │ └ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x7305f7c6ca90>
│ └ <starlette.middleware.exceptions.ExceptionMiddleware object at 0x7305f7c6ca30>
└ <function wrap_app_handling_exceptions at 0x7305f8719f30>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
│ │ │ └ <function wrap_app_handling_exceptions.<locals>.wrapped_app.<locals>.sender at 0x7305f7c7c670>
│ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
└ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x7305f7c6ca90>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions.<locals>.wrapped_app.<locals>.sender at 0x7305f7c7c670>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <fastapi.routing.APIRouter object at 0x7305f7c6c070>
└ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x7305f7c6ca90>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/routing.py", line 660, in __call__
await self.middleware_stack(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions.<locals>.wrapped_app.<locals>.sender at 0x7305f7c7c670>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <bound method Router.app of <fastapi.routing.APIRouter object at 0x7305f7c6c070>>
└ <fastapi.routing.APIRouter object at 0x7305f7c6c070>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/routing.py", line 680, in app
await route.handle(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions.<locals>.wrapped_app.<locals>.sender at 0x7305f7c7c670>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <function Route.handle at 0x7305f871b640>
└ APIRoute(path='/products/all', name='get_all_products', methods=['GET'])
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions.<locals>.wrapped_app.<locals>.sender at 0x7305f7c7c670>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <function request_response.<locals>.app at 0x7305f7c43490>
└ APIRoute(path='/products/all', name='get_all_products', methods=['GET'])
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/fastapi/routing.py", line 134, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
│ │ │ │ │ └ <function wrap_app_handling_exceptions.<locals>.wrapped_app.<locals>.sender at 0x7305f7c7c670>
│ │ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ │ └ <starlette.requests.Request object at 0x7305f7c47cd0>
│ └ <function request_response.<locals>.app.<locals>.app at 0x7305f7c7c700>
└ <function wrap_app_handling_exceptions at 0x7305f8719f30>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
│ │ │ └ <function wrap_app_handling_exceptions.<locals>.wrapped_app.<locals>.sender at 0x7305f7c7c790>
│ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7305f7c47d90>>
│ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
└ <function request_response.<locals>.app.<locals>.app at 0x7305f7c7c700>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/fastapi/routing.py", line 120, in app
response = await f(request)
│ └ <starlette.requests.Request object at 0x7305f7c47cd0>
└ <function get_request_handler.<locals>.app at 0x7305f7c43520>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/fastapi/routing.py", line 674, in app
raw_response = await run_endpoint_function(
└ <function run_endpoint_function at 0x7305f8739480>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/fastapi/routing.py", line 330, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
│ │ │ └ {}
│ │ └ <function get_all_products at 0x7305f8674ca0>
│ └ Dependant(path_params=[], query_params=[], header_params=[], cookie_params=[], body_params=[], dependencies=[], name=None, ca...
└ <function run_in_threadpool at 0x7305f89081f0>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/starlette/concurrency.py", line 32, in run_in_threadpool
return await anyio.to_thread.run_sync(func)
│ │ │ └ functools.partial(<function get_all_products at 0x7305f8674ca0>)
│ │ └ <function run_sync at 0x7305f9416560>
│ └ <module 'anyio.to_thread' from '/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/anyio/to_thread.py'>
└ <module 'anyio' from '/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/anyio/__init__.py'>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/anyio/to_thread.py", line 63, in run_sync
return await get_async_backend().run_sync_in_worker_thread(
└ <function get_async_backend at 0x7305f9415ea0>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 2518, in run_sync_in_worker_thread
return await future
└ <Future finished exception=ZeroDivisionError('division by zero')>
File "/data/python/fastapi/demo1/venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 1002, in run
result = context.run(func, *args)
File "/data/python/fastapi/demo1/app/api/products.py", line 12, in get_all_products
b = 100 / a
└ 0
ZeroDivisionError: division by zero
浙公网安备 33010602011771号