diff --git a/screenshots/error-2160x3840.webp b/screenshots/error-2160x3840.webp index 0744d33..2778d1c 100644 Binary files a/screenshots/error-2160x3840.webp and b/screenshots/error-2160x3840.webp differ diff --git a/screenshots/error-3840x2160.webp b/screenshots/error-3840x2160.webp index a5f6ed0..85a517d 100644 Binary files a/screenshots/error-3840x2160.webp and b/screenshots/error-3840x2160.webp differ diff --git a/src/api.ts b/src/api.ts index 46d4ff8..013a651 100644 --- a/src/api.ts +++ b/src/api.ts @@ -10,14 +10,15 @@ function apiUrl(instanceUrl: string, path: string): string { export class AuthError extends Error {} -async function performApiRequest( +async function apiFetch( instanceUrl: string, accessToken: string, path: string, method: 'GET' | 'PUT' = 'GET' -): Promise { +): Promise { + let response: Response try { - return await fetch(apiUrl(instanceUrl, path), { + response = await fetch(apiUrl(instanceUrl, path), { method, headers: { Authorization: `Bearer ${accessToken}`, @@ -30,27 +31,17 @@ async function performApiRequest( { cause: err } ) } -} -function classifyApiResponse(res: Response, path: string): void { - if (res.status === 401) throw new AuthError(`Unauthorized: ${path}`) - if (res.status === 404) + if (response.status === 401) throw new AuthError(`Unauthorized: ${path}`) + if (response.status === 404) throw new Error( 'The selected content could not be found. Please verify that it still exists in Salesforce.' ) - if (res.status >= 500 || res.status === 429) - throw new Error(`Salesforce's API had a problem (${res.status}).`) - if (!res.ok) throw new Error(`API error ${res.status}: ${path}`) -} + if (response.status >= 500 || response.status === 429) + throw new Error(`Salesforce's API had a problem (${response.status}).`) + if (!response.ok) throw new Error(`API error ${response.status}: ${path}`) -async function apiFetch( - instanceUrl: string, - accessToken: string, - path: string -): Promise { - const res = await performApiRequest(instanceUrl, accessToken, path) - classifyApiResponse(res, path) - return res.json() as Promise + return response.json() as Promise } export async function triggerDashboardRefresh( @@ -59,7 +50,7 @@ export async function triggerDashboardRefresh( contentId: string ): Promise { const path = `/analytics/dashboards/${contentId}` - await performApiRequest(instanceUrl, accessToken, path, 'PUT').catch(() => {}) + await apiFetch(instanceUrl, accessToken, path, 'PUT').catch(() => {}) } export async function getDashboardResults( diff --git a/src/content.ts b/src/content.ts index 9490161..42f7fbe 100644 --- a/src/content.ts +++ b/src/content.ts @@ -42,51 +42,38 @@ type CredentialsResult = | { ok: true; accessToken: string; instanceUrl: string } | { ok: false } -type LoadAttempt = - | { ok: true; content: ContentResults } - | { ok: false; error: unknown } - -type ContentResults = - | { contentType: 'dashboard'; results: DashboardResults } - | { contentType: 'report'; results: ReportResult } - async function fetchContentResults( contentType: SalesforceContentType, instanceUrl: string, accessToken: string, contentId: string -): Promise { +): Promise { if (contentType === 'dashboard') { await triggerDashboardRefresh(instanceUrl, accessToken, contentId) - const results = await getDashboardResults( - instanceUrl, - accessToken, - contentId - ) - return { contentType, results } + return getDashboardResults(instanceUrl, accessToken, contentId) } - const results = await getReportResults(instanceUrl, accessToken, contentId) - return { contentType, results } + return getReportResults(instanceUrl, accessToken, contentId) } async function loadContent( context: RenderContext, accessToken: string, instanceUrl: string -): Promise { - try { - const content = await fetchContentResults( - context.contentType, - instanceUrl, - accessToken, - context.contentId - ) - writeCachedContent(context.contentType, context.contentId, content.results) - return { ok: true, content } - } catch (err) { - return { ok: false, error: err } - } +): Promise { + const results = await fetchContentResults( + context.contentType, + instanceUrl, + accessToken, + context.contentId + ) + writeCachedContent(context.contentType, context.contentId, results) + showContent({ + contentType: context.contentType, + contentId: context.contentId, + results, + showLabels: context.showLabels, + } as ContentToRender) } function showCachedContent(context: RenderContext): void { @@ -132,25 +119,14 @@ export async function render(context: RenderContext): Promise { const credentials = requireCredentials(context) if (!credentials.ok) return - const attempt = await loadContent( - context, - credentials.accessToken, - credentials.instanceUrl - ) - - if (attempt.ok) { - showContent({ - ...attempt.content, + try { + await loadContent(context, credentials.accessToken, credentials.instanceUrl) + } catch (err) { + reportError(err, { + source: 'salesforce-content', contentId: context.contentId, - showLabels: context.showLabels, + contentType: context.contentType, }) - return + handleContentFailure(context, err) } - - reportError(attempt.error, { - source: 'salesforce-content', - contentId: context.contentId, - contentType: context.contentType, - }) - handleContentFailure(context, attempt.error) } diff --git a/src/main.ts b/src/main.ts index 486e8d3..10ff4fa 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,8 +7,11 @@ import { signalReady, } from '@screenly/edge-apps' import { setupSentry } from '@screenly/edge-apps/utils' -import { inferSalesforceContentType, render } from './content' -import type { RenderContext } from './content' +import { + inferSalesforceContentType, + render, + type RenderContext, +} from './content' import { createCredentialManager } from './credentials' setupSentry('salesforce', {