diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d780a5feb..5b2acf0405 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ Thanks to: @dathbe. - [calendar] Fixed broken unittest that only broke at 1st of july and 1st of january (#3830) - [clock] Fixed missing icons when no other modules with icons is loaded (#3834) +- [weather] Add error handling to fetch functions including cors (#3791) ## [2.32.0] - 2025-07-01 diff --git a/js/server_functions.js b/js/server_functions.js index 07c6df534c..72520cad68 100644 --- a/js/server_functions.js +++ b/js/server_functions.js @@ -46,19 +46,22 @@ async function cors (req, res) { const headersToSend = getHeadersToSend(req.url); const expectedReceivedHeaders = geExpectedReceivedHeaders(req.url); - Log.log(`cors url: ${url}`); - const response = await fetch(url, { headers: headersToSend }); - for (const header of expectedReceivedHeaders) { - const headerValue = response.headers.get(header); - if (header) res.set(header, headerValue); + const response = await fetch(url, { headers: headersToSend }); + if (response.ok) { + for (const header of expectedReceivedHeaders) { + const headerValue = response.headers.get(header); + if (header) res.set(header, headerValue); + } + const data = await response.text(); + res.send(data); + } else { + throw new Error(`Response status: ${response.status}`); } - const data = await response.text(); - res.send(data); } } catch (error) { - Log.error(error); + Log.error(`Error in CORS request: ${error}`); res.send(error); } } diff --git a/modules/default/utils.js b/modules/default/utils.js index 2d6e43ab10..cc9b7a1813 100644 --- a/modules/default/utils.js +++ b/modules/default/utils.js @@ -17,19 +17,28 @@ async function performWebRequest (url, type = "json", useCorsProxy = false, requ requestUrl = url; request.headers = getHeadersToSend(requestHeaders); } - const response = await fetch(requestUrl, request); - const data = await response.text(); - if (type === "xml") { - return new DOMParser().parseFromString(data, "text/html"); - } else { - if (!data || !data.length > 0) return undefined; + try { + const response = await fetch(requestUrl, request); + if (response.ok) { + const data = await response.text(); + + if (type === "xml") { + return new DOMParser().parseFromString(data, "text/html"); + } else { + if (!data || !data.length > 0) return undefined; - const dataResponse = JSON.parse(data); - if (!dataResponse.headers) { - dataResponse.headers = getHeadersFromResponse(expectedResponseHeaders, response); + const dataResponse = JSON.parse(data); + if (!dataResponse.headers) { + dataResponse.headers = getHeadersFromResponse(expectedResponseHeaders, response); + } + return dataResponse; + } + } else { + throw new Error(`Response status: ${response.status}`); } - return dataResponse; + } catch (error) { + Log.error(`Error fetching data from ${url}: ${error}`); } } diff --git a/modules/default/weather/providers/pirateweather.js b/modules/default/weather/providers/pirateweather.js index 969912f4e1..48a909c692 100644 --- a/modules/default/weather/providers/pirateweather.js +++ b/modules/default/weather/providers/pirateweather.js @@ -22,38 +22,36 @@ WeatherProvider.register("pirateweather", { lon: 0 }, - fetchCurrentWeather () { - this.fetchData(this.getUrl()) - .then((data) => { - if (!data || !data.currently || typeof data.currently.temperature === "undefined") { - // No usable data? - return; - } + async fetchCurrentWeather () { + try { + const data = await this.fetchData(this.getUrl()); + if (!data || !data.currently || typeof data.currently.temperature === "undefined") { + throw new Error("No usable data received from Pirate Weather API."); + } - const currentWeather = this.generateWeatherDayFromCurrentWeather(data); - this.setCurrentWeather(currentWeather); - }) - .catch(function (request) { - Log.error("Could not load data ... ", request); - }) - .finally(() => this.updateAvailable()); + const currentWeather = this.generateWeatherDayFromCurrentWeather(data); + this.setCurrentWeather(currentWeather); + } catch (error) { + Log.error("Could not load data ... ", error); + } finally { + this.updateAvailable(); + } }, - fetchWeatherForecast () { - this.fetchData(this.getUrl()) - .then((data) => { - if (!data || !data.daily || !data.daily.data.length) { - // No usable data? - return; - } + async fetchWeatherForecast () { + try { + const data = await this.fetchData(this.getUrl()); + if (!data || !data.daily || !data.daily.data.length) { + throw new Error("No usable data received from Pirate Weather API."); + } - const forecast = this.generateWeatherObjectsFromForecast(data.daily.data); - this.setWeatherForecast(forecast); - }) - .catch(function (request) { - Log.error("Could not load data ... ", request); - }) - .finally(() => this.updateAvailable()); + const forecast = this.generateWeatherObjectsFromForecast(data.daily.data); + this.setWeatherForecast(forecast); + } catch (error) { + Log.error("Could not load data ... ", error); + } finally { + this.updateAvailable(); + } }, // Create a URL from the config and base URL. diff --git a/tests/unit/functions/server_functions_spec.js b/tests/unit/functions/server_functions_spec.js index d394d055c3..575cc4a822 100644 --- a/tests/unit/functions/server_functions_spec.js +++ b/tests/unit/functions/server_functions_spec.js @@ -17,7 +17,8 @@ describe("server_functions tests", () => { headers: { get: fetchResponseHeadersGet }, - text: fetchResponseHeadersText + text: fetchResponseHeadersText, + ok: true }; fetch = jest.fn();