Fix error handling, especially for file uploads

This commit is contained in:
Paul Bienkowski 2021-12-06 10:09:37 +01:00
parent e95f5096db
commit 4e45ec6744
4 changed files with 25 additions and 5 deletions

View file

@ -13,7 +13,7 @@ from sanic.response import (
file as file_response, file as file_response,
html as html_response, html as html_response,
) )
from sanic.exceptions import Unauthorized from sanic.exceptions import Unauthorized, SanicException
from sanic_session import Session, InMemorySessionInterface from sanic_session import Session, InMemorySessionInterface
from sqlalchemy import select from sqlalchemy import select
@ -31,6 +31,20 @@ c = app.config
api = Blueprint("api", url_prefix="/api") api = Blueprint("api", url_prefix="/api")
auth = Blueprint("auth", url_prefix="") auth = Blueprint("auth", url_prefix="")
@api.exception(SanicException, BaseException)
def _handle_sanic_errors(_request, exception):
log.error("Exception in handler: %s", exception, exc_info=True)
return json_response(
{
"errors": {
type(exception).__name__: str(exception),
},
},
status=exception.status_code if hasattr(exception, "status_code") else 500,
)
# Configure paths # Configure paths
def configure_paths(c): def configure_paths(c):
c.API_ROOT_DIR = c.get("API_ROOT_DIR") or abspath( c.API_ROOT_DIR = c.get("API_ROOT_DIR") or abspath(

View file

@ -145,6 +145,8 @@ class Road(Base):
NOW = text("NOW()") NOW = text("NOW()")
class DuplicateTrackFileError(ValueError):
pass
class Track(Base): class Track(Base):
__tablename__ = "track" __tablename__ = "track"
@ -262,7 +264,7 @@ class Track(Base):
) )
if duplicate_count: if duplicate_count:
raise ValueError("duplicate file") raise DuplicateTrackFileError()
self.original_file_hash = hex_hash self.original_file_hash = hex_hash

View file

@ -6,7 +6,7 @@ from os.path import join, exists, isfile
from sqlalchemy import select, func from sqlalchemy import select, func
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from obs.api.db import Track, User, Comment from obs.api.db import Track, User, Comment, DuplicateTrackFileError
from obs.api.app import api, require_auth, read_api_key, json from obs.api.app import api, require_auth, read_api_key, json
from sanic.response import file_stream, empty from sanic.response import file_stream, empty
@ -112,7 +112,11 @@ async def post_track(req):
else req.ctx.user.are_tracks_visible_for_all, else req.ctx.user.are_tracks_visible_for_all,
) )
track.generate_slug() track.generate_slug()
try:
await track.prevent_duplicates(req.ctx.db, file.body) await track.prevent_duplicates(req.ctx.db, file.body)
except DuplicateTrackFileError:
raise InvalidUsage("Track file is not unique")
track.uploaded_by_user_agent = normalize_user_agent(req.headers["user-agent"]) track.uploaded_by_user_agent = normalize_user_agent(req.headers["user-agent"])
track.original_file_name = file.name track.original_file_name = file.name
await track.write_to_original_file(req.app.config, file.body) await track.write_to_original_file(req.app.config, file.body)

View file

@ -49,7 +49,7 @@ export function FileUploadStatus({
}: { }: {
id: string id: string
file: File file: File
onComplete: (result: FileUploadResult) => void onComplete: (id: string, result: FileUploadResult) => void
slug?: string slug?: string
}) { }) {
const [progress, setProgress] = React.useState(0) const [progress, setProgress] = React.useState(0)