Truncate noisy build-failure output, fix the recurring terrain death
The web UI was showing a raw ~500k-character stdout/stderr dump on a failed build — go-pmtiles' extract logs one progress line per chunk, which is fine on a terminal (it overwrites itself) but not captured non-interactively. command_output now keeps just the tail, and the status line renders it with preserved line breaks in a scrollable box instead of one unreadable blob. Root cause of the actual failure (terrain build dying ~11 minutes in with an HTTP/2 stream reset): go-pmtiles' default --overfetch=0.05 merged this multi-country planet.pmtiles extract into a single ~60GB request with no way to resume after a dropped stream. --overfetch=0 splits it into many smaller requests instead.
This commit is contained in:
1 parent
237e5b2e54
commit
f18e5c19d3
5 files changed
+92
-13
No files matched your search
@@ -206,23 +206,31 @@ class DataFileRow {
|
||||
this._refreshStatus();
|
||||
}
|
||||
|
||||
// Single place that writes to _statusEl, so the error styling (pre-wrap,
|
||||
// scrollable, red — see style.css) never stays stuck on once a build's
|
||||
// failure message has scrolled past into a normal status line.
|
||||
_setStatus(text, isError = false) {
|
||||
this._statusEl.textContent = text;
|
||||
this._statusEl.classList.toggle("offline-data-panel__status--error", isError);
|
||||
}
|
||||
|
||||
async _refreshStatus() {
|
||||
let data;
|
||||
try {
|
||||
data = await (await fetch(this._statusUrl)).json();
|
||||
} catch {
|
||||
this._statusEl.textContent = "Could not check status.";
|
||||
this._setStatus("Could not check status.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.available) {
|
||||
this._statusEl.textContent = "Not generated yet.";
|
||||
this._setStatus("Not generated yet.");
|
||||
this._deleteButton.hidden = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const updated = new Date(data.mtime).toLocaleString([], { dateStyle: "short", timeStyle: "short" });
|
||||
this._statusEl.textContent = `${formatBytes(data.size)} · updated ${updated}${this._formatMeta(data.meta)}`;
|
||||
this._setStatus(`${formatBytes(data.size)} · updated ${updated}${this._formatMeta(data.meta)}`);
|
||||
this._deleteButton.hidden = !isLoggedIn();
|
||||
this._checkUpdate();
|
||||
}
|
||||
@@ -274,7 +282,7 @@ class DataFileRow {
|
||||
// Called by OfflineDataControl once RegionPicker's Apply has saved a
|
||||
// new selection — not tied to a button of this row's own.
|
||||
async triggerBuild() {
|
||||
this._statusEl.textContent = "Checking…";
|
||||
this._setStatus("Checking…");
|
||||
try {
|
||||
// false (not null/true — see offline_update_available? in
|
||||
// pmtiles_builder.rb) means the just-saved selection matches what's
|
||||
@@ -291,17 +299,17 @@ class DataFileRow {
|
||||
// couldn't tell — fall through and build rather than silently skip
|
||||
}
|
||||
|
||||
this._statusEl.textContent = "Starting…";
|
||||
this._setStatus("Starting…");
|
||||
try {
|
||||
const response = await fetch(this._buildUrl, { method: "POST" });
|
||||
const data = await response.json().catch(() => ({}));
|
||||
if (!response.ok) throw new Error(data.error || `build failed: ${response.status}`);
|
||||
} catch (err) {
|
||||
this._statusEl.textContent = err.message;
|
||||
this._setStatus(err.message, true);
|
||||
return;
|
||||
}
|
||||
|
||||
this._statusEl.textContent = "Building…";
|
||||
this._setStatus("Building…");
|
||||
this._poll();
|
||||
}
|
||||
|
||||
@@ -318,13 +326,13 @@ class DataFileRow {
|
||||
}
|
||||
|
||||
if (status.state === "running") {
|
||||
this._statusEl.textContent = formatRunning(status);
|
||||
this._setStatus(formatRunning(status));
|
||||
this._poll();
|
||||
return;
|
||||
}
|
||||
|
||||
if (status.state === "error") {
|
||||
this._statusEl.textContent = `Build failed: ${status.message}`;
|
||||
this._setStatus(`Build failed: ${status.message}`, true);
|
||||
} else {
|
||||
this._refreshStatus();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user