mirror of https://github.com/buster-so/buster.git
Merge pull request #1115 from buster-so/big-nate-bus-1909-unexpected-error-state-needs-to-actually-ping-us-in-slack
Big nate bus 1909 unexpected error state needs to actually ping us in slack
This commit is contained in:
commit
01e5401547
|
@ -1,5 +1,5 @@
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect, useMemo } from 'react';
|
||||||
import { versionGetAppVersion } from '@/api/query_keys/version';
|
import { versionGetAppVersion } from '@/api/query_keys/version';
|
||||||
import { Text } from '@/components/ui/typography';
|
import { Text } from '@/components/ui/typography';
|
||||||
import { useWindowFocus } from '@/hooks/useWindowFocus';
|
import { useWindowFocus } from '@/hooks/useWindowFocus';
|
||||||
|
@ -53,17 +53,6 @@ export const useAppVersion = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const AppVersionMessage = () => {
|
const AppVersionMessage = () => {
|
||||||
// const [countdown, setCountdown] = useState(180);
|
|
||||||
// useEffect(() => {
|
|
||||||
// const interval = setInterval(() => {
|
|
||||||
// setCountdown((prev) => Math.max(prev - 1, 0));
|
|
||||||
// if (countdown === 0) {
|
|
||||||
// window.location.reload();
|
|
||||||
// }
|
|
||||||
// }, 1000);
|
|
||||||
// return () => clearInterval(interval);
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Text>
|
<Text>
|
||||||
A new version of the app is available. Please refresh the page to get the latest features.
|
A new version of the app is available. Please refresh the page to get the latest features.
|
||||||
|
@ -78,3 +67,12 @@ export const useIsVersionChanged = () => {
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useAppVersionMeta = () => {
|
||||||
|
const { data } = useQuery({
|
||||||
|
...versionGetAppVersion,
|
||||||
|
select: (data) => data,
|
||||||
|
notifyOnChangeProps: ['data'],
|
||||||
|
});
|
||||||
|
return useMemo(() => ({ ...data, browserBuild }), [data]);
|
||||||
|
};
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { isServer } from '@tanstack/react-query';
|
||||||
import { ClientOnly } from '@tanstack/react-router';
|
import { ClientOnly } from '@tanstack/react-router';
|
||||||
import type { PostHogConfig } from 'posthog-js';
|
import type { PostHogConfig } from 'posthog-js';
|
||||||
import React, { type PropsWithChildren, useEffect, useState } from 'react';
|
import React, { type PropsWithChildren, useEffect, useState } from 'react';
|
||||||
import { useGetUserTeams } from '@/api/buster_rest/users';
|
|
||||||
import {
|
import {
|
||||||
useGetUserBasicInfo,
|
useGetUserBasicInfo,
|
||||||
useGetUserOrganization,
|
useGetUserOrganization,
|
||||||
|
@ -10,10 +9,8 @@ import {
|
||||||
import { ComponentErrorCard } from '@/components/features/global/ComponentErrorCard';
|
import { ComponentErrorCard } from '@/components/features/global/ComponentErrorCard';
|
||||||
import { isDev } from '@/config/dev';
|
import { isDev } from '@/config/dev';
|
||||||
import { env } from '@/env';
|
import { env } from '@/env';
|
||||||
import { useMount } from '@/hooks/useMount';
|
import { useAppVersionMeta } from '../AppVersion/useAppVersion';
|
||||||
import packageJson from '../../../package.json';
|
|
||||||
|
|
||||||
const version = packageJson.version;
|
|
||||||
const POSTHOG_KEY = env.VITE_PUBLIC_POSTHOG_KEY;
|
const POSTHOG_KEY = env.VITE_PUBLIC_POSTHOG_KEY;
|
||||||
const DEBUG_POSTHOG = false;
|
const DEBUG_POSTHOG = false;
|
||||||
|
|
||||||
|
@ -38,9 +35,13 @@ const options: Partial<PostHogConfig> = {
|
||||||
session_recording: {
|
session_recording: {
|
||||||
recordBody: true,
|
recordBody: true,
|
||||||
},
|
},
|
||||||
|
api_host: '/phrp/',
|
||||||
|
ui_host: 'https://us.posthog.com',
|
||||||
|
defaults: '2025-05-24',
|
||||||
};
|
};
|
||||||
|
|
||||||
const PosthogWrapper: React.FC<PropsWithChildren> = ({ children }) => {
|
const PosthogWrapper: React.FC<PropsWithChildren> = ({ children }) => {
|
||||||
|
const appVersionMeta = useAppVersionMeta();
|
||||||
const user = useGetUserBasicInfo();
|
const user = useGetUserBasicInfo();
|
||||||
const userOrganizations = useGetUserOrganization();
|
const userOrganizations = useGetUserOrganization();
|
||||||
const userOrganizationId = userOrganizations?.id || '';
|
const userOrganizationId = userOrganizations?.id || '';
|
||||||
|
@ -60,6 +61,7 @@ const PosthogWrapper: React.FC<PropsWithChildren> = ({ children }) => {
|
||||||
import('posthog-js'),
|
import('posthog-js'),
|
||||||
import('posthog-js/react'),
|
import('posthog-js/react'),
|
||||||
]);
|
]);
|
||||||
|
console.log('posthog', posthog);
|
||||||
|
|
||||||
setPosthogModules({ posthog, PostHogProvider });
|
setPosthogModules({ posthog, PostHogProvider });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -89,8 +91,34 @@ const PosthogWrapper: React.FC<PropsWithChildren> = ({ children }) => {
|
||||||
organization: userOrganizations,
|
organization: userOrganizations,
|
||||||
});
|
});
|
||||||
posthog.group(userOrganizationId, userOrganizationName);
|
posthog.group(userOrganizationId, userOrganizationName);
|
||||||
|
|
||||||
|
// Register app version metadata to be included with all events
|
||||||
|
if (appVersionMeta) {
|
||||||
|
posthog.register({
|
||||||
|
app_version: appVersionMeta.buildId,
|
||||||
|
browser_build: appVersionMeta.browserBuild,
|
||||||
|
server_build: appVersionMeta.buildId,
|
||||||
|
version_changed: appVersionMeta.buildId !== appVersionMeta.browserBuild,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, [user?.id, userOrganizationId, userOrganizationName, posthogModules]);
|
}
|
||||||
|
}, [user?.id, userOrganizationId, userOrganizationName, posthogModules, appVersionMeta]);
|
||||||
|
|
||||||
|
// Update app version metadata when it changes after PostHog is initialized
|
||||||
|
useEffect(() => {
|
||||||
|
if (posthogModules?.posthog && appVersionMeta) {
|
||||||
|
const { posthog } = posthogModules;
|
||||||
|
|
||||||
|
if (posthog.__loaded) {
|
||||||
|
posthog.register({
|
||||||
|
app_version: appVersionMeta.buildId,
|
||||||
|
browser_build: appVersionMeta.browserBuild,
|
||||||
|
server_build: appVersionMeta.buildId,
|
||||||
|
version_changed: appVersionMeta.buildId !== appVersionMeta.browserBuild,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [appVersionMeta, posthogModules]);
|
||||||
|
|
||||||
// Show children while loading or if modules failed to load
|
// Show children while loading or if modules failed to load
|
||||||
if (isLoading || !posthogModules) {
|
if (isLoading || !posthogModules) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { Route as InfoGettingStartedRouteImport } from './routes/info/getting-st
|
||||||
import { Route as AuthResetPasswordRouteImport } from './routes/auth.reset-password'
|
import { Route as AuthResetPasswordRouteImport } from './routes/auth.reset-password'
|
||||||
import { Route as AuthLogoutRouteImport } from './routes/auth.logout'
|
import { Route as AuthLogoutRouteImport } from './routes/auth.logout'
|
||||||
import { Route as AuthLoginRouteImport } from './routes/auth.login'
|
import { Route as AuthLoginRouteImport } from './routes/auth.login'
|
||||||
|
import { Route as AppThrowRouteImport } from './routes/app.throw'
|
||||||
import { Route as AppSettingsRouteImport } from './routes/app/_settings'
|
import { Route as AppSettingsRouteImport } from './routes/app/_settings'
|
||||||
import { Route as AppAppRouteImport } from './routes/app/_app'
|
import { Route as AppAppRouteImport } from './routes/app/_app'
|
||||||
import { Route as EmbedReportReportIdRouteImport } from './routes/embed/report.$reportId'
|
import { Route as EmbedReportReportIdRouteImport } from './routes/embed/report.$reportId'
|
||||||
|
@ -212,6 +213,11 @@ const AuthLoginRoute = AuthLoginRouteImport.update({
|
||||||
path: '/login',
|
path: '/login',
|
||||||
getParentRoute: () => AuthRoute,
|
getParentRoute: () => AuthRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
const AppThrowRoute = AppThrowRouteImport.update({
|
||||||
|
id: '/throw',
|
||||||
|
path: '/throw',
|
||||||
|
getParentRoute: () => AppRoute,
|
||||||
|
} as any)
|
||||||
const AppSettingsRoute = AppSettingsRouteImport.update({
|
const AppSettingsRoute = AppSettingsRouteImport.update({
|
||||||
id: '/_settings',
|
id: '/_settings',
|
||||||
getParentRoute: () => AppRoute,
|
getParentRoute: () => AppRoute,
|
||||||
|
@ -939,6 +945,7 @@ export interface FileRoutesByFullPath {
|
||||||
'/auth': typeof AuthRouteWithChildren
|
'/auth': typeof AuthRouteWithChildren
|
||||||
'/embed': typeof EmbedRouteWithChildren
|
'/embed': typeof EmbedRouteWithChildren
|
||||||
'/healthcheck': typeof HealthcheckRoute
|
'/healthcheck': typeof HealthcheckRoute
|
||||||
|
'/app/throw': typeof AppThrowRoute
|
||||||
'/auth/login': typeof AuthLoginRoute
|
'/auth/login': typeof AuthLoginRoute
|
||||||
'/auth/logout': typeof AuthLogoutRoute
|
'/auth/logout': typeof AuthLogoutRoute
|
||||||
'/auth/reset-password': typeof AuthResetPasswordRoute
|
'/auth/reset-password': typeof AuthResetPasswordRoute
|
||||||
|
@ -1048,6 +1055,7 @@ export interface FileRoutesByTo {
|
||||||
'/embed': typeof EmbedRouteWithChildren
|
'/embed': typeof EmbedRouteWithChildren
|
||||||
'/healthcheck': typeof HealthcheckRoute
|
'/healthcheck': typeof HealthcheckRoute
|
||||||
'/app': typeof AppSettingsRestricted_layoutAdmin_onlyRouteWithChildren
|
'/app': typeof AppSettingsRestricted_layoutAdmin_onlyRouteWithChildren
|
||||||
|
'/app/throw': typeof AppThrowRoute
|
||||||
'/auth/login': typeof AuthLoginRoute
|
'/auth/login': typeof AuthLoginRoute
|
||||||
'/auth/logout': typeof AuthLogoutRoute
|
'/auth/logout': typeof AuthLogoutRoute
|
||||||
'/auth/reset-password': typeof AuthResetPasswordRoute
|
'/auth/reset-password': typeof AuthResetPasswordRoute
|
||||||
|
@ -1142,6 +1150,7 @@ export interface FileRoutesById {
|
||||||
'/healthcheck': typeof HealthcheckRoute
|
'/healthcheck': typeof HealthcheckRoute
|
||||||
'/app/_app': typeof AppAppRouteWithChildren
|
'/app/_app': typeof AppAppRouteWithChildren
|
||||||
'/app/_settings': typeof AppSettingsRouteWithChildren
|
'/app/_settings': typeof AppSettingsRouteWithChildren
|
||||||
|
'/app/throw': typeof AppThrowRoute
|
||||||
'/auth/login': typeof AuthLoginRoute
|
'/auth/login': typeof AuthLoginRoute
|
||||||
'/auth/logout': typeof AuthLogoutRoute
|
'/auth/logout': typeof AuthLogoutRoute
|
||||||
'/auth/reset-password': typeof AuthResetPasswordRoute
|
'/auth/reset-password': typeof AuthResetPasswordRoute
|
||||||
|
@ -1267,6 +1276,7 @@ export interface FileRouteTypes {
|
||||||
| '/auth'
|
| '/auth'
|
||||||
| '/embed'
|
| '/embed'
|
||||||
| '/healthcheck'
|
| '/healthcheck'
|
||||||
|
| '/app/throw'
|
||||||
| '/auth/login'
|
| '/auth/login'
|
||||||
| '/auth/logout'
|
| '/auth/logout'
|
||||||
| '/auth/reset-password'
|
| '/auth/reset-password'
|
||||||
|
@ -1376,6 +1386,7 @@ export interface FileRouteTypes {
|
||||||
| '/embed'
|
| '/embed'
|
||||||
| '/healthcheck'
|
| '/healthcheck'
|
||||||
| '/app'
|
| '/app'
|
||||||
|
| '/app/throw'
|
||||||
| '/auth/login'
|
| '/auth/login'
|
||||||
| '/auth/logout'
|
| '/auth/logout'
|
||||||
| '/auth/reset-password'
|
| '/auth/reset-password'
|
||||||
|
@ -1469,6 +1480,7 @@ export interface FileRouteTypes {
|
||||||
| '/healthcheck'
|
| '/healthcheck'
|
||||||
| '/app/_app'
|
| '/app/_app'
|
||||||
| '/app/_settings'
|
| '/app/_settings'
|
||||||
|
| '/app/throw'
|
||||||
| '/auth/login'
|
| '/auth/login'
|
||||||
| '/auth/logout'
|
| '/auth/logout'
|
||||||
| '/auth/reset-password'
|
| '/auth/reset-password'
|
||||||
|
@ -1689,6 +1701,13 @@ declare module '@tanstack/react-router' {
|
||||||
preLoaderRoute: typeof AuthLoginRouteImport
|
preLoaderRoute: typeof AuthLoginRouteImport
|
||||||
parentRoute: typeof AuthRoute
|
parentRoute: typeof AuthRoute
|
||||||
}
|
}
|
||||||
|
'/app/throw': {
|
||||||
|
id: '/app/throw'
|
||||||
|
path: '/throw'
|
||||||
|
fullPath: '/app/throw'
|
||||||
|
preLoaderRoute: typeof AppThrowRouteImport
|
||||||
|
parentRoute: typeof AppRoute
|
||||||
|
}
|
||||||
'/app/_settings': {
|
'/app/_settings': {
|
||||||
id: '/app/_settings'
|
id: '/app/_settings'
|
||||||
path: ''
|
path: ''
|
||||||
|
@ -3215,12 +3234,14 @@ const AppSettingsRouteWithChildren = AppSettingsRoute._addFileChildren(
|
||||||
interface AppRouteChildren {
|
interface AppRouteChildren {
|
||||||
AppAppRoute: typeof AppAppRouteWithChildren
|
AppAppRoute: typeof AppAppRouteWithChildren
|
||||||
AppSettingsRoute: typeof AppSettingsRouteWithChildren
|
AppSettingsRoute: typeof AppSettingsRouteWithChildren
|
||||||
|
AppThrowRoute: typeof AppThrowRoute
|
||||||
AppIndexRoute: typeof AppIndexRoute
|
AppIndexRoute: typeof AppIndexRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppRouteChildren: AppRouteChildren = {
|
const AppRouteChildren: AppRouteChildren = {
|
||||||
AppAppRoute: AppAppRouteWithChildren,
|
AppAppRoute: AppAppRouteWithChildren,
|
||||||
AppSettingsRoute: AppSettingsRouteWithChildren,
|
AppSettingsRoute: AppSettingsRouteWithChildren,
|
||||||
|
AppThrowRoute: AppThrowRoute,
|
||||||
AppIndexRoute: AppIndexRoute,
|
AppIndexRoute: AppIndexRoute,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useMount } from '../hooks/useMount';
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/app/throw')({
|
||||||
|
component: RouteComponent,
|
||||||
|
});
|
||||||
|
|
||||||
|
function RouteComponent() {
|
||||||
|
const [throwError, setThrowError] = useState(false);
|
||||||
|
|
||||||
|
useMount(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setThrowError(true);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (throwError) {
|
||||||
|
throw new Error('Nate is testing this error');
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div>Hello "/app/throw"! {throwError ? 'Throwing error' : 'Not throwing error'}</div>;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"rewrites": [
|
||||||
|
{
|
||||||
|
"source": "/phrp/static/(.*)",
|
||||||
|
"destination": "https://us-assets.i.posthog.com/static/$1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "/phrp/(.*)",
|
||||||
|
"destination": "https://us.i.posthog.com/$1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue