From b8a246f2d74b6f6edea8799ea4804a8aeec4fa86 Mon Sep 17 00:00:00 2001 From: Saxon Fletcher Date: Fri, 10 Apr 2026 20:11:02 +1000 Subject: [PATCH] Errors since last deploy (#44733) --- .../EdgeFunctionOverview.tsx | 3 +- .../EdgeFunctionRecentErrors.tsx | 94 ++++++++++++++++--- .../EdgeFunctionRecentErrors.utils.test.ts | 69 +++++++++++++- .../EdgeFunctionRecentErrors.utils.ts | 66 ++++++++++++- 4 files changed, 214 insertions(+), 18 deletions(-) diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionOverview/EdgeFunctionOverview.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionOverview/EdgeFunctionOverview.tsx index 4662337a845..55822ec9cf6 100644 --- a/apps/studio/components/interfaces/Functions/EdgeFunctionOverview/EdgeFunctionOverview.tsx +++ b/apps/studio/components/interfaces/Functions/EdgeFunctionOverview/EdgeFunctionOverview.tsx @@ -203,8 +203,7 @@ export const EdgeFunctionOverview = () => { functionId={id} functionSlug={functionSlug as string} projectRef={projectRef as string} - isoTimestampStart={selectedWindowStart.toISOString()} - isoTimestampEnd={selectedWindowEnd.toISOString()} + updatedAt={selectedFunction?.updated_at} /> { const router = useRouter() const { openSidebar } = useSidebarManagerSnapshot() const aiAssistant = useAiAssistantStateSnapshot() + const { isoTimestampStart, isoTimestampEnd } = useMemo( + () => getSinceLastDeployLogRange(updatedAt), + [updatedAt] + ) + const emptyStateFallback = + 'Runtime errors since the last deploy will appear here when this function returns a 5xx response.' - const isQueryEnabled = Boolean(projectRef && functionId) + const isQueryEnabled = Boolean(projectRef && functionId && isoTimestampStart) const recentErrorInvocationsSql = useMemo( () => getRecentErrorInvocationsSql(functionId), [functionId] ) + const sinceLastDeployInvocationCountSql = useMemo( + () => getSinceLastDeployInvocationCountSql(functionId), + [functionId] + ) const { logData: recentErrorInvocations, @@ -87,6 +99,19 @@ export const EdgeFunctionRecentErrors = ({ () => getRecentErrorGroupsBase(recentErrorInvocations), [recentErrorInvocations] ) + const { + logData: sinceLastDeployInvocationCountRows, + isLoading: isLoadingSinceLastDeployInvocationCount, + error: sinceLastDeployInvocationCountError, + } = useLogsQuery( + projectRef as string, + { + sql: sinceLastDeployInvocationCountSql, + iso_timestamp_start: isoTimestampStart, + iso_timestamp_end: isoTimestampEnd, + }, + Boolean(projectRef && sinceLastDeployInvocationCountSql && isoTimestampStart) + ) const relatedExecutionIds = useMemo( () => getRelatedExecutionIds(recentErrorGroupsBase), @@ -109,7 +134,7 @@ export const EdgeFunctionRecentErrors = ({ iso_timestamp_start: isoTimestampStart, iso_timestamp_end: isoTimestampEnd, }, - Boolean(projectRef && functionRuntimeLogsSql) + Boolean(projectRef && functionRuntimeLogsSql && isoTimestampStart) ) const queryError = toAlertError(recentErrorInvocationsError) ?? toAlertError(functionRuntimeLogsError) @@ -118,6 +143,46 @@ export const EdgeFunctionRecentErrors = ({ () => getRecentErrorGroups({ recentErrorGroupsBase, functionRuntimeLogs }), [functionRuntimeLogs, recentErrorGroupsBase] ) + const sinceLastDeployInvocationCount = useMemo( + () => getSinceLastDeployInvocationCount(sinceLastDeployInvocationCountRows), + [sinceLastDeployInvocationCountRows] + ) + const emptyStateMessage = useMemo(() => { + if (!isoTimestampStart || sinceLastDeployInvocationCountError) return emptyStateFallback + + const verb = sinceLastDeployInvocationCount === 1 ? 'has' : 'have' + const invocationPhrase = getSinceLastDeployInvocationPhrase(sinceLastDeployInvocationCount) + + return ( + <> + There {verb} been {invocationPhrase} since last + deploy and no errors. + + ) + }, [ + emptyStateFallback, + isoTimestampStart, + sinceLastDeployInvocationCount, + sinceLastDeployInvocationCountError, + ]) + const emptyStateIcon = + isoTimestampStart && !sinceLastDeployInvocationCountError ? ( + sinceLastDeployInvocationCount > 0 ? ( +