Retry failed weather fetches so the bar icon can't stay stuck

The Open-Meteo fetch is the only thing that updates the bar icon when a
location is configured, but a failed response was dropped silently with
no retry, leaving a stale icon until the next refresh tick. Give it the
same short retry loop the wttr fetch already has, and reset both retry
budgets on each full refresh cycle so an exhausted round (e.g. waking
before the network is back) doesn't starve retries for the session.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-08-03 15:40:22 -05:00
co-authored by Claude Fable 5
parent 12af188304
commit 7e9cc153db
+30 -2
View File
@@ -87,6 +87,7 @@ Panel {
onLocationQueryChanged: { onLocationQueryChanged: {
if (savingLocation) savingLocationQueryStarted = true if (savingLocation) savingLocationQueryStarted = true
forecastRetries = 0 forecastRetries = 0
dailyForecastRetries = 0
forecastProc.running = false forecastProc.running = false
dailyForecastProc.running = false dailyForecastProc.running = false
Qt.callLater(refresh) Qt.callLater(refresh)
@@ -112,6 +113,7 @@ Panel {
} }
property int forecastRetries: 0 property int forecastRetries: 0
property int dailyForecastRetries: 0
// Click-to-edit state for the location label. // Click-to-edit state for the location label.
property bool editingLocation: false property bool editingLocation: false
@@ -148,6 +150,11 @@ Panel {
readonly property string reportHumidity: current ? (current.humidity + "%") : "" readonly property string reportHumidity: current ? (current.humidity + "%") : ""
function refresh() { function refresh() {
// Each full refresh cycle gets a fresh retry budget, so an earlier
// exhausted round (e.g. waking with the network still down) doesn't
// starve retries for the rest of the session.
forecastRetries = 0
dailyForecastRetries = 0
if (!forecastProc.running) forecastProc.running = true if (!forecastProc.running) forecastProc.running = true
if (root.locationQuery === "" && !locationProc.running) locationProc.running = true if (root.locationQuery === "" && !locationProc.running) locationProc.running = true
// With stored coordinates this fetches open-meteo right away — no need // With stored coordinates this fetches open-meteo right away — no need
@@ -368,22 +375,42 @@ Panel {
onTriggered: if (!forecastProc.running) forecastProc.running = true onTriggered: if (!forecastProc.running) forecastProc.running = true
} }
// With configured coordinates this fetch is the only thing that updates the
// bar icon, so a dropped response (e.g. waking before the network is back)
// must retry rather than wait out the refresh timer with a stale icon.
function scheduleDailyForecastRetry() {
if (dailyForecastRetries >= 3) return
dailyForecastRetries++
dailyForecastRetryTimer.restart()
}
Timer {
id: dailyForecastRetryTimer
interval: 2500
onTriggered: root.refreshDailyForecast(null)
}
Process { Process {
id: dailyForecastProc id: dailyForecastProc
stdout: StdioCollector { stdout: StdioCollector {
waitForEnd: true waitForEnd: true
onStreamFinished: { onStreamFinished: {
var raw = String(text || "").trim() var raw = String(text || "").trim()
if (!raw) return if (!raw) {
root.scheduleDailyForecastRetry()
return
}
try { try {
var parsed = JSON.parse(raw) var parsed = JSON.parse(raw)
var parsedCurrent = Model.openMeteoCurrentCondition(parsed) var parsedCurrent = Model.openMeteoCurrentCondition(parsed)
root.dailyForecastReport = parsed root.dailyForecastReport = parsed
root.label = Model.currentIcon(parsedCurrent, root.label) root.label = Model.currentIcon(parsedCurrent, root.label)
root.dailyForecastRetries = 0
if (Model.weatherResponseCompletesSave(root.hasConfiguredCoordinates, "open-meteo")) if (Model.weatherResponseCompletesSave(root.hasConfiguredCoordinates, "open-meteo"))
root.finishSavingLocation() root.finishSavingLocation()
} catch (e) { } catch (e) {
// Keep last-good daily forecast on parse failure. // Keep last-good daily forecast visible, but try again shortly.
root.scheduleDailyForecastRetry()
} }
} }
} }
@@ -418,6 +445,7 @@ Panel {
if (!root.savingLocationQueryStarted) { if (!root.savingLocationQueryStarted) {
root.savingLocationQueryStarted = true root.savingLocationQueryStarted = true
root.forecastRetries = 0 root.forecastRetries = 0
root.dailyForecastRetries = 0
forecastProc.running = false forecastProc.running = false
dailyForecastProc.running = false dailyForecastProc.running = false
Qt.callLater(root.refresh) Qt.callLater(root.refresh)