WebHost: Log: handle FileNotFoundError (#3603)

This commit is contained in:
black-sliver 2024-07-02 01:03:55 +02:00 committed by GitHub
parent 401606e8e3
commit b6925c593e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 21 additions and 19 deletions

View File

@ -1,6 +1,6 @@
import datetime import datetime
import os import os
from typing import Dict, Iterator, List, Tuple, Union from typing import Any, IO, Dict, Iterator, List, Tuple, Union
import jinja2.exceptions import jinja2.exceptions
from flask import request, redirect, url_for, render_template, Response, session, abort, send_from_directory from flask import request, redirect, url_for, render_template, Response, session, abort, send_from_directory
@ -97,13 +97,13 @@ def new_room(seed: UUID):
return redirect(url_for("host_room", room=room.id)) return redirect(url_for("host_room", room=room.id))
def _read_log(path: str, offset: int = 0) -> Iterator[bytes]: def _read_log(log: IO[Any], offset: int = 0) -> Iterator[bytes]:
with open(path, "rb") as log: marker = log.read(3) # skip optional BOM
marker = log.read(3) # skip optional BOM if marker != b'\xEF\xBB\xBF':
if marker != b'\xEF\xBB\xBF': log.seek(0, os.SEEK_SET)
log.seek(0, os.SEEK_SET) log.seek(offset, os.SEEK_CUR)
log.seek(offset, os.SEEK_CUR) yield from log
yield from log log.close() # free file handle as soon as possible
@app.route('/log/<suuid:room>') @app.route('/log/<suuid:room>')
@ -114,6 +114,7 @@ def display_log(room: UUID) -> Union[str, Response, Tuple[str, int]]:
if room.owner == session["_id"]: if room.owner == session["_id"]:
file_path = os.path.join("logs", str(room.id) + ".txt") file_path = os.path.join("logs", str(room.id) + ".txt")
try: try:
log = open(file_path, "rb")
range_header = request.headers.get("Range") range_header = request.headers.get("Range")
if range_header: if range_header:
range_type, range_values = range_header.split('=') range_type, range_values = range_header.split('=')
@ -121,8 +122,8 @@ def display_log(room: UUID) -> Union[str, Response, Tuple[str, int]]:
if range_type != "bytes" or end != "": if range_type != "bytes" or end != "":
return "Unsupported range", 500 return "Unsupported range", 500
# NOTE: we skip Content-Range in the response here, which isn't great but works for our JS # NOTE: we skip Content-Range in the response here, which isn't great but works for our JS
return Response(_read_log(file_path, int(start)), mimetype="text/plain", status=206) return Response(_read_log(log, int(start)), mimetype="text/plain", status=206)
return Response(_read_log(file_path), mimetype="text/plain") return Response(_read_log(log), mimetype="text/plain")
except FileNotFoundError: except FileNotFoundError:
return Response(f"Logfile {file_path} does not exist. " return Response(f"Logfile {file_path} does not exist. "
f"Likely a crash during spinup of multiworld instance or it is still spinning up.", f"Likely a crash during spinup of multiworld instance or it is still spinning up.",
@ -152,15 +153,16 @@ def host_room(room: UUID):
def get_log(max_size: int = 1024000) -> str: def get_log(max_size: int = 1024000) -> str:
try: try:
raw_size = 0 with open(os.path.join("logs", str(room.id) + ".txt"), "rb") as log:
fragments: List[str] = [] raw_size = 0
for block in _read_log(os.path.join("logs", str(room.id) + ".txt")): fragments: List[str] = []
if raw_size + len(block) > max_size: for block in _read_log(log):
fragments.append("") if raw_size + len(block) > max_size:
break fragments.append("")
raw_size += len(block) break
fragments.append(block.decode("utf-8")) raw_size += len(block)
return "".join(fragments) fragments.append(block.decode("utf-8"))
return "".join(fragments)
except FileNotFoundError: except FileNotFoundError:
return "" return ""