You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何捕获django-main-thread中抛出的Django OperationalError异常

解决Django启动时数据库连接异常无法捕获的问题

问题原因

你遇到的异常发生在服务器启动阶段(runserver执行check_migrations步骤),这个阶段早于请求处理流程,所以常规的中间件、handler500、DRF异常处理器都无法捕获——它们只在处理单个请求时生效。

解决方案

1. 自定义runserver命令,避免启动时崩溃

创建management/commands/runserver.py文件,重写默认的runserver命令,捕获迁移检查时的数据库异常,让服务器能正常启动:

from django.core.management.commands.runserver import Command as RunserverCommand
from django.db.utils import OperationalError

class Command(RunserverCommand):
    def inner_run(self, *args, **options):
        try:
            # 尝试执行原有的启动流程(包括迁移检查)
            super().inner_run(*args, **options)
        except OperationalError as e:
            self.stdout.write(self.style.ERROR(f"数据库连接失败: {str(e)}"))
            self.stdout.write(self.style.WARNING("服务器将继续运行,无法处理依赖数据库的请求"))
            # 跳过迁移检查,直接启动HTTP服务器
            self.start_http_server(*args, **options)

2. 配置中间件捕获请求阶段的异常

更新中间件为Django 5.0推荐的写法(无需MiddlewareMixin),确保能捕获请求处理时的数据库连接异常:

from django.db.utils import OperationalError
from rest_framework import status
from rest_framework.response import Response

class OperationalErrorMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        try:
            return self.get_response(request)
        except OperationalError:
            return Response(
                {'status': "DB_ERROR", 'message': "数据库服务暂时不可用"},
                status=status.HTTP_503_SERVICE_UNAVAILABLE
            )

在settings.py的MIDDLEWARE列表中添加这个中间件(建议放在靠近顶部的位置,确保优先捕获异常):

MIDDLEWARE = [
    # ...其他中间件
    'your_app.middleware.OperationalErrorMiddleware',
    # ...其他中间件
]

3. 生产环境注意事项

生产环境使用gunicorn或uwsgi启动时,默认不会自动执行迁移检查,因此服务器不会因数据库连接失败而启动崩溃。此时只需确保中间件配置正确,即可在请求时返回友好的503响应。

内容的提问来源于stack exchange,提问作者GuiTeK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 02:24:51