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

使用Uppy与django-tus上传文件时遭遇TypeError异常求助

问题描述

前端使用Uppy,后端采用django-tus实现文件上传时,出现错误:TypeError: exceptions must derive from BaseException

错误回溯

Internal Server Error: /tus/upload/6393bfe5-277e-4c68-b9af-c0394be796b9
Traceback (most recent call last):
  File "/django_tus/tusfile.py", line 75, in get_tusfile_or_404
    raise TusResponse(status=404)
TypeError: exceptions must derive from BaseException
[06/Aug/2022 14:36:42] "HEAD /tus/upload/6393bfe5-277e-4c68-b9af-c0394be796b9 HTTP/1.1" 500 103054
[06/Aug/2022 14:36:42,624] - Broken pipe from ('127.0.0.1', 35814)

[06/Aug/2022 14:36:42] "POST /tus/upload/ HTTP/1.1" 204 0
[06/Aug/2022 14:36:42] "PATCH /tus/upload/8295bef4-c94a-4ab7-9c75-2635c74428d8 HTTP/1.1" 204 0

相关代码片段

TusUpload视图的head方法

class TusUpload(View):

    def head(self, request, resource_id):
        tus_file = TusFile.get_tusfile_or_404(str(resource_id))

        return TusResponse(
            status=200,
            extra_headers={
                'Upload-Offset': tus_file.offset,
                'Upload-Length': tus_file.file_size,
            })

create_initial_file函数

def create_initial_file(metadata, file_size: int):
        resource_id = str(uuid.uuid4())
        cache.add("tus-uploads/{}/filename".format(resource_id), "{}".format(metadata.get("filename")), settings.TUS_TIMEOUT)
        cache.add("tus-uploads/{}/file_size".format(resource_id), file_size, settings.TUS_TIMEOUT)
        cache.add("tus-uploads/{}/offset".format(resource_id), 0, settings.TUS_TIMEOUT)
        cache.add("tus-uploads/{}/metadata".format(resource_id), metadata, settings.TUS_TIMEOUT)

        tus_file = TusFile(resource_id)
        tus_file.write_init_file()
        return tus_file
解决方案

错误核心是get_tusfile_or_404方法中尝试抛出TusResponse对象,但TusResponse是HTTP响应类,并非继承自BaseException的异常类,Python不允许抛出非异常类型的对象。

有两种修复方式:

方式1:直接返回404响应

修改get_tusfile_or_404方法,找不到文件时直接返回TusResponse(status=404),并在视图中判断返回值:

# 修改get_tusfile_or_404方法
def get_tusfile_or_404(resource_id):
    # 原有文件查找逻辑
    tus_file = ... # 你的文件查找代码
    if not tus_file:
        return TusResponse(status=404)
    return tus_file

# 修改head视图方法
def head(self, request, resource_id):
    result = TusFile.get_tusfile_or_404(str(resource_id))
    if isinstance(result, TusResponse):
        return result
    tus_file = result
    return TusResponse(
        status=200,
        extra_headers={
            'Upload-Offset': tus_file.offset,
            'Upload-Length': tus_file.file_size,
        })

方式2:抛出Django内置404异常

借助Django的Http404异常,让框架自动处理404响应:

from django.http import Http404

# 修改get_tusfile_or_404方法
def get_tusfile_or_404(resource_id):
    tus_file = ... # 你的文件查找代码
    if not tus_file:
        raise Http404("Tus上传文件不存在")
    return tus_file

两种方式都能符合TUS协议的404响应要求,推荐方式2,更贴合Django的开发规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:06:23