diff --git a/web/oss/src/components/pages/observability/components/EmptyObservability/index.tsx b/web/oss/src/components/pages/observability/components/EmptyObservability/index.tsx
index 902bdf92a1..ac16fae612 100644
--- a/web/oss/src/components/pages/observability/components/EmptyObservability/index.tsx
+++ b/web/oss/src/components/pages/observability/components/EmptyObservability/index.tsx
@@ -1,25 +1,66 @@
import {memo} from "react"
-import {BranchesOutlined} from "@ant-design/icons"
+import {BranchesOutlined, StopOutlined} from "@ant-design/icons"
import {Typography} from "antd"
import {useSetAtom} from "jotai"
+import Link from "next/link"
import EmptyState from "@/oss/components/EmptyState"
import {EMPTY_STATE_VIDEOS} from "@/oss/components/EmptyState/videos"
import EmptyComponent from "@/oss/components/Placeholders/EmptyComponent"
+import useURL from "@/oss/hooks/useURL"
import {setOnboardingWidgetActivationAtom} from "@/oss/lib/onboarding"
interface EmptyObservabilityProps {
showOnboarding?: boolean
+ rateLimited?: boolean
+ rateLimitMessage?: string
}
-const EmptyObservability = ({showOnboarding = true}: EmptyObservabilityProps) => {
+const EmptyObservability = ({
+ showOnboarding = true,
+ rateLimited = false,
+ rateLimitMessage,
+}: EmptyObservabilityProps) => {
const setOnboardingWidgetActivation = useSetAtom(setOnboardingWidgetActivationAtom)
+ const {projectURL} = useURL()
+ const subscriptionHref = projectURL
+ ? `${projectURL}/settings?tab=billing&upgrade=true`
+ : undefined
const handleSetupTracing = () => {
setOnboardingWidgetActivation("tracing-snippet")
}
+ if (rateLimited) {
+ return (
+
diff --git a/web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx b/web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx
index c8ffa73b42..3ad9f25a52 100644
--- a/web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx
+++ b/web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx
@@ -75,6 +75,8 @@ const ObservabilityTable = () => {
isFetchingMore,
autoRefresh,
fetchAnnotations,
+ isRateLimited,
+ rateLimitMessage,
} = useObservability()
const setTraceDrawerActiveSpan = useSetAtom(setTraceDrawerActiveSpanAtom)
const isNewUser = useAtomValue(isNewUserAtom)
@@ -186,7 +188,7 @@ const ObservabilityTable = () => {
}
const showTableLoading = isLoading && traces.length === 0
- const isEmptyState = traces.length === 0 && !isLoading
+ const isEmptyState = traces.length === 0 && !isLoading && !isRateLimited
const showOnboarding = isNewUser && !hasReceivedTraces
useEffect(() => {
@@ -226,7 +228,9 @@ const ObservabilityTable = () => {
refreshTrigger={refreshTrigger}
/>
- {isEmptyState ? (
+ {isRateLimited ? (
+
+ ) : isEmptyState ? (
) : (
diff --git a/web/oss/src/state/newObservability/hooks/index.ts b/web/oss/src/state/newObservability/hooks/index.ts
index 850f96280d..19d7622490 100644
--- a/web/oss/src/state/newObservability/hooks/index.ts
+++ b/web/oss/src/state/newObservability/hooks/index.ts
@@ -52,6 +52,8 @@ export const useObservability = () => {
isLoading: isLoadingTraces,
isFetching: isFetchingTraces,
isRefetching: isRefetchingTraces,
+ isError: isTracesError,
+ error: tracesError,
},
] = useAtom(tracesQueryAtom)
@@ -82,6 +84,11 @@ export const useObservability = () => {
[isFetchingTraces, isFetchingAnnotations, isRefetchingTraces, isRefetchingAnnotations],
)
+ const isRateLimited = isTracesError && (tracesError as {status?: number})?.status === 429
+ const rateLimitMessage = isRateLimited
+ ? (tracesError as Error)?.message || "You have reached your monthly quota limit."
+ : undefined
+
const fetchTraces = useCallback(async () => {
const res = await refetchTraces()
return res.data
@@ -111,6 +118,8 @@ export const useObservability = () => {
annotations,
isLoading:
isLoadingObservability || isLoadingTraces || isLoadingAnnotations || isRefreshing,
+ isRateLimited,
+ rateLimitMessage,
fetchMoreTraces,
hasMoreTraces: hasNextPage,
isFetchingMore: isFetchingNextPage,