- 在 package.json 和 package-lock.json 中新增 @sentry/react-native、react-native-device-info 和 react-native-purchases 依赖 - 更新统计页面,替换 CircularRing 组件为 FitnessRingsCard,增强健身数据展示 - 在布局文件中引入 ToastProvider,优化用户通知体验 - 新增 SuccessToast 组件,提供全局成功提示功能 - 更新健康数据获取逻辑,支持健身圆环数据的提取 - 优化多个组件的样式和交互,提升用户体验
113 lines
3.0 KiB
TypeScript
113 lines
3.0 KiB
TypeScript
import * as Sentry from '@sentry/react-native';
|
|
|
|
export const captureException = (error: Error) => {
|
|
Sentry.captureException(error);
|
|
};
|
|
|
|
export const captureMessage = (message: string) => {
|
|
Sentry.captureMessage(message);
|
|
};
|
|
|
|
// 智能处理大型对象的日志记录,避免截断
|
|
export const captureMessageWithContext = (
|
|
message: string,
|
|
context?: Record<string, any>,
|
|
level: 'debug' | 'info' | 'warning' | 'error' = 'info'
|
|
) => {
|
|
try {
|
|
// 如果有上下文数据,优先使用 addBreadcrumb 或 setContext
|
|
if (context) {
|
|
// 检查 JSON 字符串长度
|
|
const contextString = JSON.stringify(context);
|
|
|
|
if (contextString.length > 7000) { // 留 1000+ 字符给消息本身
|
|
// 如果上下文数据太大,将其作为 context 附加到事件
|
|
Sentry.withScope(scope => {
|
|
scope.setContext('large_data', context);
|
|
Sentry.captureMessage(`${message} (大型上下文数据已附加到事件上下文)`, level);
|
|
});
|
|
} else {
|
|
// 数据较小时,直接包含在消息中
|
|
Sentry.captureMessage(`${message}: ${contextString}`, level);
|
|
}
|
|
} else {
|
|
Sentry.captureMessage(message, level);
|
|
}
|
|
} catch (error) {
|
|
// 如果 JSON.stringify 失败,回退到基本消息
|
|
console.error('序列化上下文数据失败:', error);
|
|
Sentry.captureMessage(`${message} (上下文数据序列化失败)`, level);
|
|
}
|
|
};
|
|
|
|
// 专门用于记录购买相关的日志,带有结构化数据
|
|
export const capturePurchaseEvent = (
|
|
eventType: 'init' | 'success' | 'error' | 'restore',
|
|
message: string,
|
|
data?: any
|
|
) => {
|
|
const tags = {
|
|
event_type: 'purchase',
|
|
purchase_action: eventType,
|
|
};
|
|
|
|
Sentry.withScope(scope => {
|
|
// 设置标签
|
|
Object.entries(tags).forEach(([key, value]) => {
|
|
scope.setTag(key, value);
|
|
});
|
|
|
|
// 如果有数据,设置为上下文
|
|
if (data) {
|
|
scope.setContext('purchase_data', data);
|
|
}
|
|
|
|
// 根据事件类型设置适当的级别
|
|
const level = eventType === 'error' ? 'error' : 'info';
|
|
Sentry.captureMessage(message, level);
|
|
});
|
|
};
|
|
|
|
// 记录用户操作日志
|
|
export const captureUserAction = (
|
|
action: string,
|
|
details?: Record<string, any>
|
|
) => {
|
|
Sentry.addBreadcrumb({
|
|
message: `用户操作: ${action}`,
|
|
category: 'user_action',
|
|
data: details,
|
|
level: 'info',
|
|
});
|
|
};
|
|
|
|
// 记录 API 调用日志
|
|
export const captureApiCall = (
|
|
endpoint: string,
|
|
method: string,
|
|
success: boolean,
|
|
responseData?: any,
|
|
error?: Error
|
|
) => {
|
|
const breadcrumb = {
|
|
message: `API ${method} ${endpoint}`,
|
|
category: 'http',
|
|
data: {
|
|
method,
|
|
endpoint,
|
|
success,
|
|
} as any,
|
|
level: success ? 'info' : 'error' as any,
|
|
};
|
|
|
|
if (success && responseData) {
|
|
// 对于成功的响应,只记录关键信息避免数据过大
|
|
breadcrumb.data.response_keys = Object.keys(responseData);
|
|
}
|
|
|
|
if (error) {
|
|
breadcrumb.data.error = error.message;
|
|
}
|
|
|
|
Sentry.addBreadcrumb(breadcrumb);
|
|
}; |