diff --git a/scripts/patch-listening-endpoint-runtime-guards.mjs b/scripts/patch-listening-endpoint-runtime-guards.mjs index 472b1f58..6789a832 100644 --- a/scripts/patch-listening-endpoint-runtime-guards.mjs +++ b/scripts/patch-listening-endpoint-runtime-guards.mjs @@ -96,7 +96,7 @@ const patchSpecs = [ newSnippet: ` const causeCode = String(err?.cause?.code || ""); if ( /fetch failed/i.test(message) || - /ECONNREFUSED|ENOTFOUND|ETIMEDOUT/.test(causeCode) + /ECONNREFUSED|ENOTFOUND|ETIMEDOUT|ECONNRESET/.test(causeCode) ) { // Cannot reach Funkwhale instance; skipping sync console.warn( @@ -551,6 +551,116 @@ const patchSpecs = [ "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-lastfm/lib/stats.js", ], }, + { + name: "funkwhale-sync-econnreset-guard", + marker: "ECONNRESET added to network error guard", + oldSnippet: ` /ECONNREFUSED|ENOTFOUND|ETIMEDOUT/.test(causeCode) + ) { + // Cannot reach Funkwhale instance; skipping sync`, + newSnippet: ` // ECONNRESET added to network error guard + /ECONNREFUSED|ENOTFOUND|ETIMEDOUT|ECONNRESET/.test(causeCode) + ) { + // Cannot reach Funkwhale instance; skipping sync`, + candidates: [ + "node_modules/@rmdes/indiekit-endpoint-funkwhale/lib/sync.js", + "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-funkwhale/lib/sync.js", + ], + }, + { + name: "funkwhale-now-playing-econnreset-guard", + marker: "degrade gracefully on transient network errors (now-playing)", + oldSnippet: ` } catch (error) { + const message = String(error?.message || ""); + if (/not found/i.test(message)) { + return response.json({ + playing: false, + status: null, + message: "No recent plays", + }); + } + + console.error("[Funkwhale] Now Playing API error:", error); + response.status(500).json({ error: message || "Unknown error" }); + }`, + newSnippet: ` } catch (error) { + const message = String(error?.message || ""); + const causeCode = String(error?.cause?.code || ""); + if (/not found/i.test(message)) { + return response.json({ + playing: false, + status: null, + message: "No recent plays", + }); + } + // degrade gracefully on transient network errors (now-playing) + if (/ECONNRESET|ECONNREFUSED|ENOTFOUND|ETIMEDOUT/.test(causeCode)) { + return response.json({ + playing: false, + status: null, + message: "No recent plays", + }); + } + + console.error("[Funkwhale] Now Playing API error:", error); + response.status(500).json({ error: message || "Unknown error" }); + }`, + candidates: [ + "node_modules/@rmdes/indiekit-endpoint-funkwhale/lib/controllers/now-playing.js", + "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-funkwhale/lib/controllers/now-playing.js", + ], + }, + { + name: "funkwhale-listenings-econnreset-guard", + marker: "degrade gracefully on transient network errors (listenings)", + oldSnippet: ` } catch (error) { + const message = String(error?.message || ""); + if (/not found/i.test(message)) { + const fallbackPage = Number.parseInt(request.query.page, 10) || 1; + return response.json({ + listenings: [], + total: 0, + page: fallbackPage, + hasNext: false, + hasPrev: false, + }); + } + + console.error("[Funkwhale] Listenings API error:", error); + response.status(500).json({ error: message || "Unknown error" }); + }`, + newSnippet: ` } catch (error) { + const message = String(error?.message || ""); + const causeCode = String(error?.cause?.code || ""); + if (/not found/i.test(message)) { + const fallbackPage = Number.parseInt(request.query.page, 10) || 1; + return response.json({ + listenings: [], + total: 0, + page: fallbackPage, + hasNext: false, + hasPrev: false, + }); + } + // degrade gracefully on transient network errors (listenings) + if (/ECONNRESET|ECONNREFUSED|ENOTFOUND|ETIMEDOUT/.test(causeCode)) { + const fallbackPage = Number.parseInt(request.query.page, 10) || 1; + return response.json({ + listenings: [], + total: 0, + page: fallbackPage, + hasNext: false, + hasPrev: false, + }); + } + + console.error("[Funkwhale] Listenings API error:", error); + response.status(500).json({ error: message || "Unknown error" }); + }`, + candidates: [ + "node_modules/@rmdes/indiekit-endpoint-funkwhale/lib/controllers/listenings.js", + "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-funkwhale/lib/controllers/listenings.js", + ], + }, { name: "lastfm-trends-date-coercion", marker: "support string and Date scrobbledAt values in trends aggregation",