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

Django Rest Framework自定义异常处理器失效,返回HTML而非JSON

解决Django异常返回JSON而非HTML的问题

我来帮你排查并修复这个问题——你已经做了基础的自定义异常处理器配置,但还有几个关键细节没覆盖到,导致依然返回HTML页面。

1. 核心问题分析

出现这个情况通常有几个原因:

  • Django原生异常(比如Http404)可能绕过DRF处理器,触发Django默认的错误页面
  • 响应没有明确指定JSON格式,DRF可能根据请求头做内容协商返回HTML
  • DEBUG模式下Django会强制显示调试HTML页面

2. 修改自定义异常处理器

调整你的处理器函数,确保所有返回的响应都是结构化JSON,并且强制指定content_type:

from django.http import Http404
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import exception_handler
import logging

# 导入你的自定义异常类
from your_app.exceptions import DeisException, ServiceUnavailable, HealthcheckException

def custom_exception_handler(exc, context):
    # 处理Http404:返回结构化JSON而非纯文本
    if isinstance(exc, Http404):
        logging.exception('Uncaught Exception', exc_info=exc)
        return Response(
            {'detail': str(exc)}, 
            status=status.HTTP_404_NOT_FOUND,
            content_type='application/json'  # 强制JSON格式
        )
    
    # 调用DRF默认异常处理器
    response = exception_handler(exc, context)
    
    # 处理DRF无法识别的异常(比如服务器内部错误)
    if response is None:
        logging.exception('Uncaught Exception', exc_info=exc)
        return Response(
            {'detail': 'Server Error'}, 
            status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            content_type='application/json'
        )
    
    # 处理自定义异常,确保返回JSON
    if isinstance(exc, (DeisException, ServiceUnavailable, HealthcheckException)):
        logging.exception(exc.__cause__, exc_info=exc)
        response.content_type = 'application/json'
        return response
    
    # 对所有DRF处理的异常,强制JSON格式
    response.content_type = 'application/json'
    return response

3. 优化Settings配置

确保DRF的渲染器优先使用JSON,并且异常处理器路径正确:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'your_app.views.custom_exception_handler',  # 确认路径无误
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',  # 优先JSON渲染
        # 若不需要可浏览API,可移除下面一行
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}

4. 调试模式的特殊处理

如果你的DEBUG = True,Django会强制显示调试HTML页面,哪怕你返回了JSON。可以:

  • 临时设置DEBUG = False测试(记得配置ALLOWED_HOSTS)
  • 或者在调试时,给请求添加Accept: application/json头,DRF会优先返回JSON

5. 确认请求目标是DRF视图

DRF的异常处理器只对DRF视图(比如APIView、ViewSet)生效,如果是普通Django视图,依然会走Django默认错误处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:42:49