prometheus: submit page shows what the server actually returned

The 'Unexpected token <' error landed the user in a dead-end — the
message named the failure (JSON.parse choked on an HTML body) but hid
the body itself. Now the submit path reads the response as text first,
tries JSON.parse, and on failure surfaces the HTTP status, the content
type, and the first 180 chars of the body with tags stripped. That tells
a publisher 'Caddy returned 413, max body size X' instead of 'Network
error'. Pure diagnostic — no change to the success path.
This commit is contained in:
Local Dev 2026-10-24 00:57:38 +03:00
parent 09bb42f7a6
commit 85098bf989

View file

@ -606,6 +606,8 @@ export function submit() {
};
const $ = (id) => document.getElementById(id);
const esc = (s) => String(s).replace(/[&<>"']/g, (c) => (
{'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
const SUBS = {
1: 'the binary (up to 2 GiB — free below 100 MiB)',
2: 'name, publisher name, category, description',
@ -713,7 +715,21 @@ export function submit() {
let json;
try {
const r = await fetch('/api/upload', { method: 'POST', body });
json = await r.json();
// Read as text first — if the server returned an HTML error page
// (Caddy 413/502, a cached old vhost, etc.) the JSON.parse below
// throws "Unexpected token '<'" and the user has no idea what
// actually came back. Show them the HTTP status and the first
// chunk of the body instead.
const text = await r.text();
try {
json = JSON.parse(text);
} catch (parseErr) {
const preview = text.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 180);
status.innerHTML = '⚠️ <b>Server returned non-JSON</b> — HTTP ' + r.status +
' (' + (r.headers.get('content-type') || 'no content-type') + ')' +
(preview ? '. Snippet: <code class="inline">' + esc(preview) + '</code>' : '');
return;
}
} catch (err) {
status.innerHTML = '⚠️ <b>Network error</b> — ' + String(err?.message || err);
return;