fix: sentry tracing
This commit is contained in:
parent
8ba4056187
commit
4a0f3ab7ef
2 changed files with 217 additions and 215 deletions
|
@ -346,65 +346,67 @@ export default async function trackLocation() {
|
|||
if (count > 0) {
|
||||
locationLogger.info(`Found ${count} pending records, forcing sync`);
|
||||
|
||||
const transaction = Sentry.startTransaction({
|
||||
name: "force-sync-pending-records",
|
||||
op: "geolocation-sync",
|
||||
});
|
||||
await Sentry.startSpan(
|
||||
{
|
||||
name: "force-sync-pending-records",
|
||||
op: "geolocation-sync",
|
||||
},
|
||||
async (span) => {
|
||||
try {
|
||||
const { userToken } = getAuthState();
|
||||
const state = await BackgroundGeolocation.getState();
|
||||
if (userToken && state.enabled) {
|
||||
const records = await BackgroundGeolocation.sync();
|
||||
locationLogger.debug("Forced sync result", {
|
||||
recordsCount: records?.length || 0,
|
||||
});
|
||||
|
||||
try {
|
||||
const { userToken } = getAuthState();
|
||||
const state = await BackgroundGeolocation.getState();
|
||||
if (userToken && state.enabled) {
|
||||
const records = await BackgroundGeolocation.sync();
|
||||
locationLogger.debug("Forced sync result", {
|
||||
recordsCount: records?.length || 0,
|
||||
});
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Forced sync completed",
|
||||
category: "geolocation",
|
||||
level: "info",
|
||||
data: {
|
||||
recordsCount: records?.length || 0,
|
||||
hadToken: true,
|
||||
wasEnabled: true,
|
||||
},
|
||||
});
|
||||
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Forced sync completed",
|
||||
category: "geolocation",
|
||||
level: "info",
|
||||
data: {
|
||||
recordsCount: records?.length || 0,
|
||||
hadToken: true,
|
||||
wasEnabled: true,
|
||||
},
|
||||
});
|
||||
span.setStatus("ok");
|
||||
} else {
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Forced sync skipped",
|
||||
category: "geolocation",
|
||||
level: "warning",
|
||||
data: {
|
||||
hasToken: !!userToken,
|
||||
isEnabled: state.enabled,
|
||||
},
|
||||
});
|
||||
|
||||
transaction.setStatus("ok");
|
||||
} else {
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Forced sync skipped",
|
||||
category: "geolocation",
|
||||
level: "warning",
|
||||
data: {
|
||||
hasToken: !!userToken,
|
||||
isEnabled: state.enabled,
|
||||
},
|
||||
});
|
||||
span.setStatus("cancelled");
|
||||
}
|
||||
} catch (error) {
|
||||
locationLogger.error("Forced sync failed", {
|
||||
error: error,
|
||||
stack: error.stack,
|
||||
});
|
||||
|
||||
transaction.setStatus("cancelled");
|
||||
}
|
||||
} catch (error) {
|
||||
locationLogger.error("Forced sync failed", {
|
||||
error: error,
|
||||
stack: error.stack,
|
||||
});
|
||||
Sentry.captureException(error, {
|
||||
tags: {
|
||||
module: "track-location",
|
||||
operation: "force-sync-pending",
|
||||
},
|
||||
contexts: {
|
||||
pendingRecords: { count },
|
||||
},
|
||||
});
|
||||
|
||||
Sentry.captureException(error, {
|
||||
tags: {
|
||||
module: "track-location",
|
||||
operation: "force-sync-pending",
|
||||
},
|
||||
contexts: {
|
||||
pendingRecords: { count },
|
||||
},
|
||||
});
|
||||
|
||||
transaction.setStatus("internal_error");
|
||||
} finally {
|
||||
transaction.finish();
|
||||
}
|
||||
span.setStatus("internal_error");
|
||||
throw error; // Re-throw to ensure span captures the error
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
locationLogger.error("Failed to get pending records count", {
|
||||
|
|
|
@ -12,176 +12,176 @@ const logger = createLogger({
|
|||
|
||||
// Background task to cancel expired notifications
|
||||
const backgroundTask = async () => {
|
||||
const transaction = Sentry.startTransaction({
|
||||
name: "auto-cancel-expired-notifications",
|
||||
op: "background-task",
|
||||
});
|
||||
|
||||
Sentry.getCurrentScope().setSpan(transaction);
|
||||
|
||||
try {
|
||||
logger.info("Starting auto-cancel expired notifications task");
|
||||
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Auto-cancel task started",
|
||||
category: "notifications",
|
||||
level: "info",
|
||||
});
|
||||
|
||||
// Get displayed notifications with timeout protection
|
||||
const getNotificationsSpan = transaction.startChild({
|
||||
op: "get-displayed-notifications",
|
||||
description: "Getting displayed notifications",
|
||||
});
|
||||
|
||||
let notifications;
|
||||
try {
|
||||
// Add timeout protection for the API call
|
||||
notifications = await Promise.race([
|
||||
notifee.getDisplayedNotifications(),
|
||||
new Promise((_, reject) =>
|
||||
setTimeout(
|
||||
() => reject(new Error("Timeout getting notifications")),
|
||||
10000,
|
||||
),
|
||||
),
|
||||
]);
|
||||
getNotificationsSpan.setStatus("ok");
|
||||
} catch (error) {
|
||||
getNotificationsSpan.setStatus("internal_error");
|
||||
throw error;
|
||||
} finally {
|
||||
getNotificationsSpan.finish();
|
||||
}
|
||||
|
||||
if (!Array.isArray(notifications)) {
|
||||
logger.warn("No notifications array received", { notifications });
|
||||
Sentry.addBreadcrumb({
|
||||
message: "No notifications array received",
|
||||
category: "notifications",
|
||||
level: "warning",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const currentTime = Math.round(new Date() / 1000);
|
||||
let cancelledCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
logger.info("Processing notifications", {
|
||||
totalNotifications: notifications.length,
|
||||
currentTime,
|
||||
});
|
||||
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Processing notifications",
|
||||
category: "notifications",
|
||||
level: "info",
|
||||
data: {
|
||||
totalNotifications: notifications.length,
|
||||
currentTime,
|
||||
},
|
||||
});
|
||||
|
||||
// Process notifications with individual error handling
|
||||
for (const notification of notifications) {
|
||||
await Sentry.startSpan(
|
||||
{
|
||||
name: "auto-cancel-expired-notifications",
|
||||
op: "background-task",
|
||||
},
|
||||
async (span) => {
|
||||
try {
|
||||
if (!notification || !notification.id) {
|
||||
logger.warn("Invalid notification object", { notification });
|
||||
continue;
|
||||
}
|
||||
logger.info("Starting auto-cancel expired notifications task");
|
||||
|
||||
const expires = notification.data?.expires;
|
||||
if (!expires) {
|
||||
continue; // Skip notifications without expiry
|
||||
}
|
||||
|
||||
if (typeof expires !== "number" || expires < currentTime) {
|
||||
logger.debug("Cancelling expired notification", {
|
||||
notificationId: notification.id,
|
||||
expires,
|
||||
currentTime,
|
||||
expired: expires < currentTime,
|
||||
});
|
||||
|
||||
// Cancel notification with timeout protection
|
||||
await Promise.race([
|
||||
notifee.cancelNotification(notification.id),
|
||||
new Promise((_, reject) =>
|
||||
setTimeout(
|
||||
() => reject(new Error("Timeout cancelling notification")),
|
||||
5000,
|
||||
),
|
||||
),
|
||||
]);
|
||||
|
||||
cancelledCount++;
|
||||
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Notification cancelled",
|
||||
category: "notifications",
|
||||
level: "info",
|
||||
data: {
|
||||
notificationId: notification.id,
|
||||
expires,
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (notificationError) {
|
||||
errorCount++;
|
||||
logger.error("Failed to process notification", {
|
||||
error: notificationError,
|
||||
notificationId: notification?.id,
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Auto-cancel task started",
|
||||
category: "notifications",
|
||||
level: "info",
|
||||
});
|
||||
|
||||
Sentry.captureException(notificationError, {
|
||||
// Get displayed notifications with timeout protection
|
||||
let notifications;
|
||||
await Sentry.startSpan(
|
||||
{
|
||||
op: "get-displayed-notifications",
|
||||
description: "Getting displayed notifications",
|
||||
},
|
||||
async (getNotificationsSpan) => {
|
||||
try {
|
||||
// Add timeout protection for the API call
|
||||
notifications = await Promise.race([
|
||||
notifee.getDisplayedNotifications(),
|
||||
new Promise((_, reject) =>
|
||||
setTimeout(
|
||||
() => reject(new Error("Timeout getting notifications")),
|
||||
10000,
|
||||
),
|
||||
),
|
||||
]);
|
||||
getNotificationsSpan.setStatus("ok");
|
||||
} catch (error) {
|
||||
getNotificationsSpan.setStatus("internal_error");
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (!Array.isArray(notifications)) {
|
||||
logger.warn("No notifications array received", { notifications });
|
||||
Sentry.addBreadcrumb({
|
||||
message: "No notifications array received",
|
||||
category: "notifications",
|
||||
level: "warning",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const currentTime = Math.round(new Date() / 1000);
|
||||
let cancelledCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
logger.info("Processing notifications", {
|
||||
totalNotifications: notifications.length,
|
||||
currentTime,
|
||||
});
|
||||
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Processing notifications",
|
||||
category: "notifications",
|
||||
level: "info",
|
||||
data: {
|
||||
totalNotifications: notifications.length,
|
||||
currentTime,
|
||||
},
|
||||
});
|
||||
|
||||
// Process notifications with individual error handling
|
||||
for (const notification of notifications) {
|
||||
try {
|
||||
if (!notification || !notification.id) {
|
||||
logger.warn("Invalid notification object", { notification });
|
||||
continue;
|
||||
}
|
||||
|
||||
const expires = notification.data?.expires;
|
||||
if (!expires) {
|
||||
continue; // Skip notifications without expiry
|
||||
}
|
||||
|
||||
if (typeof expires !== "number" || expires < currentTime) {
|
||||
logger.debug("Cancelling expired notification", {
|
||||
notificationId: notification.id,
|
||||
expires,
|
||||
currentTime,
|
||||
expired: expires < currentTime,
|
||||
});
|
||||
|
||||
// Cancel notification with timeout protection
|
||||
await Promise.race([
|
||||
notifee.cancelNotification(notification.id),
|
||||
new Promise((_, reject) =>
|
||||
setTimeout(
|
||||
() => reject(new Error("Timeout cancelling notification")),
|
||||
5000,
|
||||
),
|
||||
),
|
||||
]);
|
||||
|
||||
cancelledCount++;
|
||||
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Notification cancelled",
|
||||
category: "notifications",
|
||||
level: "info",
|
||||
data: {
|
||||
notificationId: notification.id,
|
||||
expires,
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (notificationError) {
|
||||
errorCount++;
|
||||
logger.error("Failed to process notification", {
|
||||
error: notificationError,
|
||||
notificationId: notification?.id,
|
||||
});
|
||||
|
||||
Sentry.captureException(notificationError, {
|
||||
tags: {
|
||||
module: "auto-cancel-expired",
|
||||
operation: "cancel-notification",
|
||||
},
|
||||
contexts: {
|
||||
notification: {
|
||||
id: notification?.id,
|
||||
expires: notification?.data?.expires,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Auto-cancel task completed", {
|
||||
totalNotifications: notifications.length,
|
||||
cancelledCount,
|
||||
errorCount,
|
||||
});
|
||||
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Auto-cancel task completed",
|
||||
category: "notifications",
|
||||
level: "info",
|
||||
data: {
|
||||
totalNotifications: notifications.length,
|
||||
cancelledCount,
|
||||
errorCount,
|
||||
},
|
||||
});
|
||||
|
||||
span.setStatus("ok");
|
||||
} catch (error) {
|
||||
logger.error("Auto-cancel task failed", { error });
|
||||
|
||||
Sentry.captureException(error, {
|
||||
tags: {
|
||||
module: "auto-cancel-expired",
|
||||
operation: "cancel-notification",
|
||||
},
|
||||
contexts: {
|
||||
notification: {
|
||||
id: notification?.id,
|
||||
expires: notification?.data?.expires,
|
||||
},
|
||||
operation: "background-task",
|
||||
},
|
||||
});
|
||||
|
||||
span.setStatus("internal_error");
|
||||
throw error; // Re-throw to be handled by caller
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Auto-cancel task completed", {
|
||||
totalNotifications: notifications.length,
|
||||
cancelledCount,
|
||||
errorCount,
|
||||
});
|
||||
|
||||
Sentry.addBreadcrumb({
|
||||
message: "Auto-cancel task completed",
|
||||
category: "notifications",
|
||||
level: "info",
|
||||
data: {
|
||||
totalNotifications: notifications.length,
|
||||
cancelledCount,
|
||||
errorCount,
|
||||
},
|
||||
});
|
||||
|
||||
transaction.setStatus("ok");
|
||||
} catch (error) {
|
||||
logger.error("Auto-cancel task failed", { error });
|
||||
|
||||
Sentry.captureException(error, {
|
||||
tags: {
|
||||
module: "auto-cancel-expired",
|
||||
operation: "background-task",
|
||||
},
|
||||
});
|
||||
|
||||
transaction.setStatus("internal_error");
|
||||
throw error; // Re-throw to be handled by caller
|
||||
} finally {
|
||||
transaction.finish();
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const useAutoCancelExpired = () => {
|
||||
|
|
Loading…
Add table
Reference in a new issue