mirror of
https://github.com/SlimeVR/SlimeVR-Server.git
synced 2026-04-06 02:01:58 +02:00
Sentry fixes
This commit is contained in:
@@ -20,8 +20,8 @@
|
||||
"@tauri-apps/plugin-dialog": "^2.0.0",
|
||||
"@tauri-apps/plugin-fs": "2.4.1",
|
||||
"@tauri-apps/plugin-http": "^2.5.0",
|
||||
"@tauri-apps/plugin-opener": "^2.4.0",
|
||||
"@tauri-apps/plugin-log": "~2",
|
||||
"@tauri-apps/plugin-opener": "^2.4.0",
|
||||
"@tauri-apps/plugin-os": "^2.0.0",
|
||||
"@tauri-apps/plugin-shell": "^2.3.0",
|
||||
"@tauri-apps/plugin-store": "^2.4.1",
|
||||
@@ -52,6 +52,7 @@
|
||||
"ts-pattern": "^5.4.0",
|
||||
"typescript": "^5.6.3",
|
||||
"use-double-tap": "^1.3.6",
|
||||
"uuid": "^13.0.0",
|
||||
"yup": "^1.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,30 +1,16 @@
|
||||
import { ReactNode, useContext, useLayoutEffect } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import { ConfigContextC, loadConfig, useConfigProvider } from '@/hooks/config';
|
||||
import { DEFAULT_LOCALE, LangContext } from '@/i18n/config';
|
||||
import { getSentryOrCompute } from '@/utils/sentry';
|
||||
|
||||
const config = await loadConfig();
|
||||
|
||||
if (config?.errorTracking !== undefined) {
|
||||
// load sentry ASAP to catch early errors
|
||||
getSentryOrCompute(config.errorTracking ?? false);
|
||||
getSentryOrCompute(config.errorTracking ?? false, config.uuid);
|
||||
}
|
||||
|
||||
export function ConfigContextProvider({ children }: { children: ReactNode }) {
|
||||
const context = useConfigProvider(config);
|
||||
const { changeLocales } = useContext(LangContext);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
changeLocales([config?.lang || DEFAULT_LOCALE]);
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (config?.errorTracking !== undefined) {
|
||||
// Alows for sentry to refresh if user change the setting once the gui
|
||||
// is initialized
|
||||
getSentryOrCompute(config.errorTracking ?? false);
|
||||
}
|
||||
}, [config?.errorTracking]);
|
||||
|
||||
return (
|
||||
<ConfigContextC.Provider value={context}>
|
||||
|
||||
@@ -55,16 +55,10 @@ export function TrackingChecklistSettings({
|
||||
// that prevent sending a packet for steps that didnt change
|
||||
if (!value && !ignoredSteps.includes(stepId)) {
|
||||
ignoreStep(stepId, true);
|
||||
Sentry.metrics.count('mute_checklist_step', 1, {
|
||||
attributes: { step: TrackingChecklistStepId[stepId] },
|
||||
});
|
||||
}
|
||||
|
||||
if (value && ignoredSteps.includes(stepId)) {
|
||||
ignoreStep(stepId, false);
|
||||
Sentry.metrics.count('unmute_checklist_step', 1, {
|
||||
attributes: { step: TrackingChecklistStepId[stepId] },
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { createContext, useContext, useEffect, useLayoutEffect, useState } from 'react';
|
||||
import {
|
||||
DataFeedMessage,
|
||||
DataFeedUpdateT,
|
||||
@@ -12,8 +12,9 @@ import { useBonesDataFeedConfig, useDataFeedConfig } from './datafeed-config';
|
||||
import { useWebsocketAPI } from './websocket-api';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { bonesAtom, datafeedAtom, devicesAtom } from '@/store/app-store';
|
||||
import { updateSentryContext } from '@/utils/sentry';
|
||||
import { getSentryOrCompute, updateSentryContext } from '@/utils/sentry';
|
||||
import { fetchCurrentFirmwareRelease, FirmwareRelease } from './firmware-update';
|
||||
import { DEFAULT_LOCALE, LangContext } from '@/i18n/config';
|
||||
|
||||
export interface AppContext {
|
||||
currentFirmwareRelease: FirmwareRelease | null;
|
||||
@@ -22,6 +23,7 @@ export interface AppContext {
|
||||
export function useProvideAppContext(): AppContext {
|
||||
const { useRPCPacket, sendDataFeedPacket, useDataFeedPacket, isConnected } =
|
||||
useWebsocketAPI();
|
||||
const { changeLocales } = useContext(LangContext);
|
||||
const { config } = useConfig();
|
||||
const { dataFeedConfig } = useDataFeedConfig();
|
||||
const bonesDataFeedConfig = useBonesDataFeedConfig();
|
||||
@@ -58,14 +60,32 @@ export function useProvideAppContext(): AppContext {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!config) return;
|
||||
|
||||
const interval = setInterval(() => {
|
||||
fetchCurrentFirmwareRelease().then((res) => setCurrentFirmwareRelease(res));
|
||||
fetchCurrentFirmwareRelease(config.uuid).then((res) =>
|
||||
setCurrentFirmwareRelease(res)
|
||||
);
|
||||
}, 1000);
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, [config?.uuid]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
changeLocales([config?.lang || DEFAULT_LOCALE]);
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!config) return;
|
||||
if (config.errorTracking !== undefined) {
|
||||
console.log('change');
|
||||
// Alows for sentry to refresh if user change the setting once the gui
|
||||
// is initialized
|
||||
getSentryOrCompute(config.errorTracking ?? false, config.uuid);
|
||||
}
|
||||
}, [config]);
|
||||
|
||||
return {
|
||||
currentFirmwareRelease,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createContext, useContext, useState } from 'react';
|
||||
import { createContext, useContext, useEffect, useLayoutEffect, useState } from 'react';
|
||||
import {
|
||||
defaultValues as defaultDevSettings,
|
||||
DeveloperModeWidgetForm,
|
||||
@@ -9,6 +9,7 @@ import { load, Store } from '@tauri-apps/plugin-store';
|
||||
import { useIsTauri } from './breakpoint';
|
||||
import { waitUntil } from '@/utils/a11y';
|
||||
import { isTauri } from '@tauri-apps/api/core';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
export interface WindowConfig {
|
||||
width: number;
|
||||
@@ -26,6 +27,7 @@ export enum AssignMode {
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
uuid: string;
|
||||
debug: boolean;
|
||||
lang: string;
|
||||
doneOnboarding: boolean;
|
||||
@@ -57,6 +59,7 @@ export interface ConfigContext {
|
||||
}
|
||||
|
||||
export const defaultConfig: Config = {
|
||||
uuid: uuidv4(),
|
||||
lang: 'en',
|
||||
debug: false,
|
||||
doneOnboarding: false,
|
||||
@@ -117,13 +120,15 @@ export const loadConfig = async () => {
|
||||
if (!json) throw new Error('Config has ceased existing for some reason');
|
||||
|
||||
const loadedConfig = fallbackToDefaults(JSON.parse(json));
|
||||
// set(loadedConfig);
|
||||
// setLoading(false);
|
||||
|
||||
if (!loadedConfig.uuid) { // Make sure the config always has a uuid
|
||||
loadedConfig.uuid = uuidv4();
|
||||
await store.set('config.json', JSON.stringify(loadedConfig))
|
||||
}
|
||||
|
||||
return loadedConfig;
|
||||
} catch (e) {
|
||||
error(e);
|
||||
// setConfig(defaultConfig);
|
||||
// setLoading(false);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// implemetation of https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
export function hash(str: string) {
|
||||
export function normalizedHash(str: string) {
|
||||
let hash = 2166136261;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
hash ^= str.charCodeAt(i);
|
||||
|
||||
@@ -2,8 +2,7 @@ import { BoardType, DeviceDataT } from 'solarxr-protocol';
|
||||
import { fetch as tauriFetch } from '@tauri-apps/plugin-http';
|
||||
import { cacheWrap } from './cache';
|
||||
import semver from 'semver';
|
||||
import { hash } from './crypto';
|
||||
import { getUserID } from './user';
|
||||
import { normalizedHash } from './crypto';
|
||||
|
||||
export interface FirmwareRelease {
|
||||
name: string;
|
||||
@@ -24,7 +23,7 @@ const todaysRange = (deployData: [number, Date][]): number => {
|
||||
return maxRange;
|
||||
};
|
||||
|
||||
const checkUserCanUpdate = async (url: string, fwVersion: string) => {
|
||||
const checkUserCanUpdate = async (uuid: string, url: string, fwVersion: string) => {
|
||||
const deployDataJson = JSON.parse(
|
||||
(await cacheWrap(
|
||||
`firmware-${fwVersion}-deploy`,
|
||||
@@ -56,12 +55,11 @@ const checkUserCanUpdate = async (url: string, fwVersion: string) => {
|
||||
const todayUpdateRange = todaysRange(deployData);
|
||||
if (!todayUpdateRange) return false;
|
||||
|
||||
const uniqueUserKey = await getUserID();
|
||||
// Make it so the hash change every version. Prevent the same user from getting the same delay
|
||||
return hash(`${uniqueUserKey}-${fwVersion}`) <= todayUpdateRange;
|
||||
return normalizedHash(`${uuid}-${fwVersion}`) <= todayUpdateRange;
|
||||
};
|
||||
|
||||
export async function fetchCurrentFirmwareRelease(): Promise<FirmwareRelease | null> {
|
||||
export async function fetchCurrentFirmwareRelease(uuid: string): Promise<FirmwareRelease | null> {
|
||||
const releases: any[] | null = JSON.parse(
|
||||
(await cacheWrap(
|
||||
'firmware-releases',
|
||||
@@ -93,6 +91,7 @@ export async function fetchCurrentFirmwareRelease(): Promise<FirmwareRelease | n
|
||||
}
|
||||
|
||||
const userCanUpdate = await checkUserCanUpdate(
|
||||
uuid,
|
||||
deployAsset.browser_download_url,
|
||||
version
|
||||
);
|
||||
|
||||
@@ -47,7 +47,12 @@ export function useReset(options: UseResetOptions, onReseted?: () => void) {
|
||||
req.bodyParts = parts;
|
||||
sendRPCPacket(RpcMessage.ResetRequest, req);
|
||||
|
||||
Sentry.metrics.count('reset_click', 1, { attributes: options });
|
||||
Sentry.metrics.count('reset_click', 1, {
|
||||
attributes: {
|
||||
resetType: ResetType[options.type],
|
||||
group: options.type === ResetType.Mounting ? options.group : undefined,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const onResetFinished = () => {
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from 'solarxr-protocol';
|
||||
import { useWebsocketAPI } from './websocket-api';
|
||||
import { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import * as Sentry from '@sentry/react';
|
||||
|
||||
export const trackingchecklistIdtoLabel: Record<TrackingChecklistStepId, string> = {
|
||||
[TrackingChecklistStepId.UNKNOWN]: '',
|
||||
@@ -165,6 +166,9 @@ export function provideTrackingChecklist() {
|
||||
res.stepId = step;
|
||||
res.ignore = ignore;
|
||||
sendRPCPacket(RpcMessage.IgnoreTrackingChecklistStepRequest, res);
|
||||
Sentry.metrics.count('mute_checklist_step', 1, {
|
||||
attributes: { step: TrackingChecklistStepId[step] },
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
import { locale, hostname, platform, version } from '@tauri-apps/plugin-os';
|
||||
import { hash } from './crypto';
|
||||
|
||||
export async function getUserID() {
|
||||
// FIXME: This does not support android. It currently return the same id for all android users
|
||||
|
||||
return hash(`${await hostname()}-${await locale()}-${platform()}-${version()}`);
|
||||
}
|
||||
@@ -8,9 +8,9 @@ import {
|
||||
useNavigationType,
|
||||
} from 'react-router-dom';
|
||||
import { DeviceDataT } from 'solarxr-protocol';
|
||||
import { getUserID } from '@/hooks/user';
|
||||
|
||||
export function getSentryOrCompute(enabled = false) {
|
||||
export function getSentryOrCompute(enabled = false, uuid: string) {
|
||||
Sentry.setUser({ id: uuid });
|
||||
// if sentry is already initialized - SKIP
|
||||
if (enabled && Sentry.isInitialized()) return;
|
||||
|
||||
@@ -63,10 +63,6 @@ export function getSentryOrCompute(enabled = false) {
|
||||
log('Initialized the Sentry client');
|
||||
}
|
||||
|
||||
getUserID().then((id) => {
|
||||
Sentry.setUser({ id });
|
||||
});
|
||||
|
||||
return newClient;
|
||||
}
|
||||
|
||||
|
||||
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
@@ -161,6 +161,9 @@ importers:
|
||||
use-double-tap:
|
||||
specifier: ^1.3.6
|
||||
version: 1.3.6(react@18.3.1)
|
||||
uuid:
|
||||
specifier: ^13.0.0
|
||||
version: 13.0.0
|
||||
yup:
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.0
|
||||
@@ -4534,6 +4537,10 @@ packages:
|
||||
resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
uuid@13.0.0:
|
||||
resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==}
|
||||
hasBin: true
|
||||
|
||||
uuid@9.0.1:
|
||||
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
||||
hasBin: true
|
||||
@@ -9720,6 +9727,8 @@ snapshots:
|
||||
|
||||
utility-types@3.11.0: {}
|
||||
|
||||
uuid@13.0.0: {}
|
||||
|
||||
uuid@9.0.1: {}
|
||||
|
||||
vfile-message@4.0.2:
|
||||
|
||||
Reference in New Issue
Block a user