fix: harden degraded source handling
This commit is contained in:
@@ -50,29 +50,29 @@ const THRESHOLDS = {
|
||||
|
||||
// Get recent RadNet analytical results (JSON)
|
||||
export async function getAnalyticalResults(opts = {}) {
|
||||
const { rows = 50, startRow = 0 } = opts;
|
||||
const { rows = 50, startRow = 0, timeout = 10000 } = opts;
|
||||
return safeFetch(
|
||||
`${RADNET_ANALYTICAL}/ROWS/${startRow}:${startRow + rows}/JSON`,
|
||||
{ timeout: 25000 }
|
||||
{ timeout, retries: 0, source: 'EPA RadNet' }
|
||||
);
|
||||
}
|
||||
|
||||
// Get results filtered by state
|
||||
export async function getResultsByState(state, opts = {}) {
|
||||
const { rows = 25, startRow = 0 } = opts;
|
||||
const { rows = 25, startRow = 0, timeout = 8000 } = opts;
|
||||
return safeFetch(
|
||||
`${RADNET_ANALYTICAL}/ANA_STATE/${state}/ROWS/${startRow}:${startRow + rows}/JSON`,
|
||||
{ timeout: 25000 }
|
||||
{ timeout, retries: 0, source: 'EPA RadNet' }
|
||||
);
|
||||
}
|
||||
|
||||
// Get results filtered by analyte type
|
||||
export async function getResultsByAnalyte(analyte, opts = {}) {
|
||||
const { rows = 25, startRow = 0 } = opts;
|
||||
const { rows = 25, startRow = 0, timeout = 8000 } = opts;
|
||||
const encoded = encodeURIComponent(analyte);
|
||||
return safeFetch(
|
||||
`${RADNET_ANALYTICAL}/ANA_TYPE/${encoded}/ROWS/${startRow}:${startRow + rows}/JSON`,
|
||||
{ timeout: 25000 }
|
||||
{ timeout, retries: 0, source: 'EPA RadNet' }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -129,7 +129,20 @@ export async function briefing() {
|
||||
const signals = [];
|
||||
|
||||
// Fetch recent analytical results (broad pull)
|
||||
const recentData = await getAnalyticalResults({ rows: 100 });
|
||||
const recentData = await getAnalyticalResults({ rows: 80, timeout: 10000 });
|
||||
if (recentData?.error) {
|
||||
return {
|
||||
source: 'EPA RadNet',
|
||||
timestamp: new Date().toISOString(),
|
||||
status: 'degraded',
|
||||
error: recentData.error,
|
||||
message: 'EPA RadNet broad analytical endpoint did not return current data within the source budget.',
|
||||
readings: [],
|
||||
signals: ['EPA RadNet unavailable — cannot assess official US radiation readings'],
|
||||
monitoredAnalytes: KEY_ANALYTES,
|
||||
thresholds: THRESHOLDS,
|
||||
};
|
||||
}
|
||||
const recentRecords = Array.isArray(recentData) ? recentData : [];
|
||||
|
||||
// Compact all readings
|
||||
@@ -137,15 +150,21 @@ export async function briefing() {
|
||||
readings.push(...allReadings);
|
||||
|
||||
// Also try to pull key analytes specifically
|
||||
const analyteResults = await Promise.all(
|
||||
const analyteResults = await Promise.allSettled(
|
||||
['GROSS BETA', 'IODINE-131', 'CESIUM-137'].map(async analyte => {
|
||||
const data = await getResultsByAnalyte(analyte, { rows: 20 });
|
||||
const data = await getResultsByAnalyte(analyte, { rows: 10, timeout: 6000 });
|
||||
const records = Array.isArray(data) ? data : [];
|
||||
return { analyte, records: records.map(compactReading) };
|
||||
})
|
||||
);
|
||||
|
||||
for (const { analyte, records } of analyteResults) {
|
||||
const analyteErrors = [];
|
||||
for (const item of analyteResults) {
|
||||
if (item.status !== 'fulfilled') {
|
||||
analyteErrors.push(item.reason?.message || 'unknown analyte fetch error');
|
||||
continue;
|
||||
}
|
||||
const { records } = item.value;
|
||||
// Add any records not already in our list
|
||||
for (const r of records) {
|
||||
if (!readings.some(existing =>
|
||||
@@ -196,6 +215,8 @@ export async function briefing() {
|
||||
return {
|
||||
source: 'EPA RadNet',
|
||||
timestamp: new Date().toISOString(),
|
||||
status: analyteErrors.length ? 'degraded' : 'ok',
|
||||
...(analyteErrors.length ? { error: 'epa_analyte_fetch_degraded', analyteErrors: analyteErrors.slice(0, 3) } : {}),
|
||||
totalReadings: readings.length,
|
||||
readings: readings.slice(0, 50), // cap for briefing size
|
||||
stateSummary,
|
||||
|
||||
Reference in New Issue
Block a user