使用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
相关产品推荐
相关产品推荐

