From 24538147212a8307d8df409bdcfe5834e73de0d9 Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Fri, 11 Oct 2024 16:59:48 +0300 Subject: [PATCH 1/9] Improve error display --- src/api/EpiData.ts | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/api/EpiData.ts b/src/api/EpiData.ts index 1b3dfc5..aae1ac5 100644 --- a/src/api/EpiData.ts +++ b/src/api/EpiData.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/restrict-template-expressions */ import UIkit from 'uikit'; import { appendIssueToTitle } from '../components/dialogs/utils'; import { @@ -142,18 +143,42 @@ export function loadDataSet( url.searchParams.set('format', 'json'); return fetchImpl[]>(url) .then((res) => { - const data = loadEpidata(title, res, columns, columnRenamings, { _endpoint: endpoint, ...params }); - if (data.datasets.length == 0) { + try { + const data = loadEpidata(title, res, columns, columnRenamings, { _endpoint: endpoint, ...params }); + if (data.datasets.length == 0) { + return UIkit.modal + .alert( + ` +
+ API Link returned no data. +
`, + ) + .then(() => null); + } + return data; + } catch (error) { + console.warn('failed loading data', error); + // EpiData API error - JSON with "message" property + if ('message' in res) { + return UIkit.modal + .alert( + ` +
+ Failed to fetch API data from API Link:
${res['message']} +
`, + ) + .then(() => null); + } + // Fallback for generic error return UIkit.modal .alert( `
- API Link returned no data. + Failed to fetch API data from API Link.
`, ) .then(() => null); } - return data; }) .catch((error) => { console.warn('failed fetching data', error); From 7982b5d4b519d9b2cc2a745797c051b2b7dba5ac Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Fri, 11 Oct 2024 17:03:44 +0300 Subject: [PATCH 2/9] Italics --- src/api/EpiData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/EpiData.ts b/src/api/EpiData.ts index aae1ac5..ddf7149 100644 --- a/src/api/EpiData.ts +++ b/src/api/EpiData.ts @@ -164,7 +164,7 @@ export function loadDataSet( .alert( `
- Failed to fetch API data from API Link:
${res['message']} + Failed to fetch API data from API Link:
${res['message']}
`, ) .then(() => null); From 64afa0426d9aa4a8b9a896b467bf7bdf91839c91 Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Thu, 21 Nov 2024 20:47:25 +0200 Subject: [PATCH 3/9] Review fixes --- src/api/EpiData.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/api/EpiData.ts b/src/api/EpiData.ts index 64fa04d..e447acd 100644 --- a/src/api/EpiData.ts +++ b/src/api/EpiData.ts @@ -48,7 +48,13 @@ export function fetchImpl(url: URL): Promise { const urlGetS = url.toString(); if (urlGetS.length < 4096) { // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return fetch(url.toString(), fetchOptions).then((d) => d.json()); + return fetch(url.toString(), fetchOptions).then((d) => { + try { + return d.json(); + } catch (error) { + throw new Error(`[${d.status}] ${d.text()}`); + } + }); } const params = new URLSearchParams(url.searchParams); url.searchParams.forEach((d) => url.searchParams.delete(d)); @@ -57,7 +63,13 @@ export function fetchImpl(url: URL): Promise { ...fetchOptions, method: 'POST', body: params, - }).then((d) => d.json()); + }).then((d) => { + try { + return d.json(); + } catch (error) { + throw new Error(`[${d.status}] ${d.text()}`); + } + }); } // generic epidata loader @@ -155,7 +167,7 @@ export function loadDataSet( .alert( `
- API Link returned no data. + API Link returned no data, which suggests that the API has no available information for the selected location.
`, ) .then(() => null); From be5b0332e8514bec4264bc553551725b3f719eb6 Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Wed, 11 Dec 2024 19:09:17 +0200 Subject: [PATCH 4/9] Add error to modal --- src/api/EpiData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/EpiData.ts b/src/api/EpiData.ts index e447acd..4aef483 100644 --- a/src/api/EpiData.ts +++ b/src/api/EpiData.ts @@ -191,7 +191,7 @@ export function loadDataSet( .alert( `
- Failed to fetch API data from API Link. + Failed to fetch API data from API Link:
${error}
`, ) .then(() => null); From cc81acba19a95f311ba143c47f1e78efa2f1faa4 Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Wed, 18 Dec 2024 16:38:00 +0200 Subject: [PATCH 5/9] Try explicit return --- src/api/EpiData.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/api/EpiData.ts b/src/api/EpiData.ts index 4aef483..18a03e4 100644 --- a/src/api/EpiData.ts +++ b/src/api/EpiData.ts @@ -44,16 +44,26 @@ const ENDPOINT = process.env.EPIDATA_ENDPOINT_URL; export const fetchOptions: RequestInit = process.env.NODE_ENV === 'development' ? { cache: 'force-cache' } : {}; +function processResponse(response: Response): Promise { + try { + if (response.status == 429) { + throw new Error( + 'Rate limit exceeded for anonymous queries. To remove this limit, register a free API key at https://api.delphi.cmu.edu/epidata/admin/registration_form

', + ); + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return response.json(); + } catch (error) { + throw new Error(`[${response.status}] ${response.text()}`); + } +} + export function fetchImpl(url: URL): Promise { const urlGetS = url.toString(); if (urlGetS.length < 4096) { // eslint-disable-next-line @typescript-eslint/no-unsafe-return return fetch(url.toString(), fetchOptions).then((d) => { - try { - return d.json(); - } catch (error) { - throw new Error(`[${d.status}] ${d.text()}`); - } + return processResponse(d); }); } const params = new URLSearchParams(url.searchParams); @@ -64,11 +74,7 @@ export function fetchImpl(url: URL): Promise { method: 'POST', body: params, }).then((d) => { - try { - return d.json(); - } catch (error) { - throw new Error(`[${d.status}] ${d.text()}`); - } + return processResponse(d); }); } From 9e4cb118764ec05dd23fd603321e64dc9f97fb0d Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Wed, 18 Dec 2024 16:42:43 +0200 Subject: [PATCH 6/9] Try without explicit return --- src/api/EpiData.ts | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/api/EpiData.ts b/src/api/EpiData.ts index 18a03e4..98e98bf 100644 --- a/src/api/EpiData.ts +++ b/src/api/EpiData.ts @@ -44,26 +44,16 @@ const ENDPOINT = process.env.EPIDATA_ENDPOINT_URL; export const fetchOptions: RequestInit = process.env.NODE_ENV === 'development' ? { cache: 'force-cache' } : {}; -function processResponse(response: Response): Promise { - try { - if (response.status == 429) { - throw new Error( - 'Rate limit exceeded for anonymous queries. To remove this limit, register a free API key at https://api.delphi.cmu.edu/epidata/admin/registration_form

', - ); - } - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return response.json(); - } catch (error) { - throw new Error(`[${response.status}] ${response.text()}`); - } -} - export function fetchImpl(url: URL): Promise { const urlGetS = url.toString(); if (urlGetS.length < 4096) { // eslint-disable-next-line @typescript-eslint/no-unsafe-return return fetch(url.toString(), fetchOptions).then((d) => { - return processResponse(d); + try { + return d.json(); + } catch (error) { + throw new Error(`[${d.status}] ${d.text()}`); + } }); } const params = new URLSearchParams(url.searchParams); @@ -74,7 +64,11 @@ export function fetchImpl(url: URL): Promise { method: 'POST', body: params, }).then((d) => { - return processResponse(d); + try { + return d.json(); + } catch (error) { + throw new Error(`[${d.status}] ${d.text()}`); + } }); } @@ -209,7 +203,7 @@ export function loadDataSet( .alert( `
- Failed to fetch API data from API Link. + Failed to fetch API data from API Link:
${error}
`, ) .then(() => null); From b0c541ebfceab8bbd39e4ef15e560f92bae77d48 Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Wed, 18 Dec 2024 16:49:06 +0200 Subject: [PATCH 7/9] Different order --- src/api/EpiData.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/api/EpiData.ts b/src/api/EpiData.ts index 98e98bf..f158732 100644 --- a/src/api/EpiData.ts +++ b/src/api/EpiData.ts @@ -44,16 +44,22 @@ const ENDPOINT = process.env.EPIDATA_ENDPOINT_URL; export const fetchOptions: RequestInit = process.env.NODE_ENV === 'development' ? { cache: 'force-cache' } : {}; +function processResponse(response: Response): Promise { + if (response.ok) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return response.json(); + } + return response.text().then((text) => { + throw new Error(`[${response.status}] ${text}`); + }); +} + export function fetchImpl(url: URL): Promise { const urlGetS = url.toString(); if (urlGetS.length < 4096) { // eslint-disable-next-line @typescript-eslint/no-unsafe-return return fetch(url.toString(), fetchOptions).then((d) => { - try { - return d.json(); - } catch (error) { - throw new Error(`[${d.status}] ${d.text()}`); - } + return processResponse(d); }); } const params = new URLSearchParams(url.searchParams); @@ -64,11 +70,7 @@ export function fetchImpl(url: URL): Promise { method: 'POST', body: params, }).then((d) => { - try { - return d.json(); - } catch (error) { - throw new Error(`[${d.status}] ${d.text()}`); - } + return processResponse(d); }); } @@ -203,7 +205,7 @@ export function loadDataSet( .alert( `
- Failed to fetch API data from API Link:
${error} + Failed to fetch API data from API Link.
`, ) .then(() => null); From 85662ec24dc08a720e18a1606ba88fb956fd2e9f Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Wed, 18 Dec 2024 16:52:01 +0200 Subject: [PATCH 8/9] Show error --- src/api/EpiData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/EpiData.ts b/src/api/EpiData.ts index f158732..53b395d 100644 --- a/src/api/EpiData.ts +++ b/src/api/EpiData.ts @@ -205,7 +205,7 @@ export function loadDataSet( .alert( `
- Failed to fetch API data from API Link. + Failed to fetch API data from API Link:
${error}
`, ) .then(() => null); From 5c244f316bd6a776df69e4164d40d0daa0e04685 Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Thu, 6 Feb 2025 16:52:31 +0200 Subject: [PATCH 9/9] Error codes --- src/api/EpiData.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/EpiData.ts b/src/api/EpiData.ts index 53b395d..8612320 100644 --- a/src/api/EpiData.ts +++ b/src/api/EpiData.ts @@ -183,7 +183,7 @@ export function loadDataSet( .alert( `
- Failed to fetch API data from API Link:
${res['message']} + [f01] Failed to fetch API data from API Link:
${res['message']}
`, ) .then(() => null); @@ -193,7 +193,7 @@ export function loadDataSet( .alert( `
- Failed to fetch API data from API Link:
${error} + [f02] Failed to fetch API data from API Link:
${error}
`, ) .then(() => null); @@ -205,7 +205,7 @@ export function loadDataSet( .alert( `
- Failed to fetch API data from API Link:
${error} + [f03] Failed to fetch API data from API Link:
${error}
`, ) .then(() => null);