Skip to content

Commit ad2de5e

Browse files
committed
Fix several bugs in crash reporter
- `[object Object]` was shown instead of stack trace - Pseudonyms starting with 0 where not logged at all - Removed field `origin` since this info is already contained in stacktrace
1 parent bfefe85 commit ad2de5e

File tree

4 files changed

+32
-26
lines changed

4 files changed

+32
-26
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@
157157
"ipympl",
158158
"ISDEBUGGROUP",
159159
"itsdangerous",
160+
"jquery",
160161
"kaniko",
161162
"keepends",
162163
"kolloqskill",
@@ -185,6 +186,7 @@
185186
"Nmbr",
186187
"noopener",
187188
"noreferrer",
189+
"noscript",
188190
"NOTREACHED",
189191
"NOTSTARTED",
190192
"nullable",
@@ -225,6 +227,7 @@
225227
"splitted",
226228
"sqlalchemy",
227229
"sqlite",
230+
"stylesheet",
228231
"subfolders",
229232
"Teilnehmer",
230233
"thinkaloud",

app/router/routerGame.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,15 +458,18 @@ def crashReport():
458458
"""Called by the server when an exception escapes to the browser or `console.error()` is called"""
459459
serverTime = now()
460460

461-
writeCrashReport(
461+
successful = writeCrashReport(
462462
pseudonym=request.form.get('ui', 'Unknown'),
463463
group=request.form.get('group', 'Unknown'),
464464
timestamp=serverTime,
465465
message=request.form.get('message', 'NoMessage'),
466466
stackTrace=request.form.get('trace', '')
467467
)
468468

469-
return 'error information send', 200
469+
if successful:
470+
return 'error information send', 200
471+
else:
472+
return 'error information rejected', 400
470473

471474

472475
def getDefaultUrl(request: Any):

app/storage/crashReport.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
from io import TextIOWrapper
22
from typing import Optional
33

4-
from prometheus_client import Gauge
5-
64
from app.config import MAX_ERROR_LOGS_PER_PLAYER, PSEUDONYM_LENGTH
75
from app.prometheusMetrics import ServerMetrics
86
from app.storage.participantsDict import exists
97
from app.utilsGame import now
108

119
crashReportFile: Optional[TextIOWrapper] = None
1210

13-
crashCounts: dict[int, int] = {}
11+
crashCounts: dict[str, int] = {}
1412
groupBlacklist: list[str]
1513

1614
def openCrashReporterFile(filePath: str, p_groupBlacklist: list[str], errorLevel: int):
@@ -39,34 +37,38 @@ def writeCrashReport(pseudonym: str, group: str, timestamp: int, message: str, s
3937
else:
4038
assert crashReportFile is not None
4139

42-
ui_num = int(pseudonym[:PSEUDONYM_LENGTH], base=16)
43-
san_pseudonym = hex(ui_num)[2:] # make sure string is a hex number, remove 0x prefix
44-
san_timestamp = str(timestamp)
45-
san_message = '%20'.join(str(message.strip()).splitlines(keepends=False))
46-
san_trace = stackTrace.splitlines(keepends=False)
47-
48-
# reject if pseudonym is unknown
49-
if not exists(san_pseudonym):
40+
# make sure pseudonym is correct length and contains a hex number
41+
pseudonym = pseudonym[:PSEUDONYM_LENGTH]
42+
if not pseudonym.isalnum():
5043
return False
51-
44+
45+
# reject if pseudonym is not in player database
46+
if not exists(pseudonym):
47+
return False
48+
5249
# reject, if the player threw too many errors
53-
if ui_num not in crashCounts:
54-
crashCounts[ui_num] = 0
55-
elif MAX_ERROR_LOGS_PER_PLAYER > 0 and crashCounts[ui_num] > MAX_ERROR_LOGS_PER_PLAYER:
50+
if pseudonym not in crashCounts:
51+
crashCounts[pseudonym] = 0
52+
elif MAX_ERROR_LOGS_PER_PLAYER > 0 and crashCounts[pseudonym] > MAX_ERROR_LOGS_PER_PLAYER:
5653
return False
5754

55+
san_timestamp = int(timestamp)
56+
san_message = '%20'.join(str(message.strip()).splitlines(keepends=False))
57+
san_trace = stackTrace.splitlines(keepends=False)
58+
5859
# Update the Prometheus metrics
5960
ServerMetrics.incrementCrashMetrics()
6061

6162
# Increase the logged errors counter and return success
62-
crashCounts[int(pseudonym[:PSEUDONYM_LENGTH], base=16)] += 1
63+
crashCounts[pseudonym] += 1
6364

6465
try:
65-
crashReportFile.write('\n[' + san_timestamp + '] ui=' + san_pseudonym + ':\n')
66+
# Write to crash reporter file
67+
crashReportFile.write(f'\n[{san_timestamp}] ui="{pseudonym}":\n')
6668
crashReportFile.write(san_message)
6769

68-
for l in san_trace:
69-
crashReportFile.write('\n\t' + l.strip())
70+
for line in san_trace:
71+
crashReportFile.write('\n\t' + line.strip())
7072

7173
crashReportFile.write('\n')
7274
crashReportFile.flush()

templates/game.html

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,9 @@
141141
/**
142142
* Send a crash report to the server containing the pseudonym, message, source file and stack trace.
143143
* @param {string} message
144-
* @param {string} origin
145144
* @param {string} trace
146145
*/
147-
function sendErrorLog(message, origin, trace)
146+
function sendErrorLog(message, trace)
148147
{
149148
try
150149
{
@@ -162,7 +161,6 @@
162161
"ui=" + encodeURIComponent(pseudonym) +
163162
"&group=" + encodeURIComponent(group) +
164163
"&message=" + encodeURIComponent(message) +
165-
"&origin=" + encodeURIComponent(origin) +
166164
"&trace=" + encodeURIComponent(trace)
167165
);
168166
}
@@ -175,7 +173,7 @@
175173
// Catch all exceptions that escape into the browser
176174
window.onerror = (event, source, line, column, error) =>
177175
{
178-
sendErrorLog(error.message, source + ':' + line + (column > 2000 ? ':' + column : ''), error.stack);
176+
sendErrorLog(error.message, error.stack);
179177
return false;
180178
};
181179

@@ -193,7 +191,7 @@
193191
return; // Panic we have a problem here
194192
}
195193

196-
sendErrorLog(args[0], "console.error", "");
194+
sendErrorLog(args[0], "console.error()");
197195
consoleErrorLogger.apply(console, args);
198196
recursionBreaker = 0;
199197
};

0 commit comments

Comments
 (0)