-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Is there an existing issue for this?
- I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
- I have reviewed the documentation https://docs.sentry.io/
- I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases
How do you use Sentry?
Sentry Saas (sentry.io)
Which SDK are you using?
@sentry/node
SDK Version
10.23.0
Framework Version
No response
Link to Sentry event
No response
Reproduction Example/SDK Setup
problem with Sentry.captureCheckIn (additionaly Sentry.withMonitor), when we have super fast cronjobs
it's sync method, but under the hood it use async method
client.sendEnvelope(envelope) // without any await !!!!
and it's causes this situation
sentry server can firstly apply finish checkin and then in_progres check in
and this situation causes random Timeout errors in sentry cron dashboard
Steps to Reproduce
just try run Sentry.withMonitor without any logic inner
and sometimes you will see this timeout error
Expected Result
Okay status on every checkins
Actual Result
Timeout status on some checkins
Additional Context
Here is my solution to this, just make captureCheckIn async, we will know when in progress check in sended, so we can send finish checkin
/**
* Custom implementation of captureCheckIn with await sendEnvelope.
* Based on Sentry's ServerRuntimeClient.captureCheckIn implementation.
*
* Key differences from Sentry.captureCheckIn():
* - Uses await client.sendEnvelope() instead of fire-and-forget
* - Ensures check-in is sent before continuing execution
* - Errors propagate to caller (no silent failures)
*
* @see https://github.com/getsentry/sentry-javascript/blob/d4a2b2bc93f5d2be3d1b960f89b61e2e08e58ca4/packages/core/src/server-runtime-client.ts#L89-L151
*/
async function captureCheckInWithAwait(
checkIn: CheckIn,
monitorConfig?: MonitorConfig,
): Promise<string> {
const client = Sentry.getClient();
if (!client) {
console.warn('[Sentry] Client not initialized, skipping check-in');
return '';
}
const id = 'checkInId' in checkIn && checkIn.checkInId ? checkIn.checkInId : uuid4();
// Get client options
const options = client.getOptions();
const { release, environment, tunnel } = options;
// Build serialized check-in
const serializedCheckIn: SerializedCheckIn = {
check_in_id: id,
monitor_slug: checkIn.monitorSlug,
status: checkIn.status,
release,
environment,
};
// Add duration if present
if ('duration' in checkIn) {
serializedCheckIn.duration = checkIn.duration;
}
// Add monitor config if provided (for upsert)
if (monitorConfig) {
serializedCheckIn.monitor_config = {
schedule: monitorConfig.schedule,
checkin_margin: monitorConfig.checkinMargin,
max_runtime: monitorConfig.maxRuntime,
timezone: monitorConfig.timezone,
failure_issue_threshold: monitorConfig.failureIssueThreshold,
recovery_threshold: monitorConfig.recoveryThreshold,
};
}
// Get trace context and dynamic sampling context from current scope
// Implementation based on Sentry's _getTraceInfoFromScope
const scope = getCurrentScope();
const [dynamicSamplingContext, traceContext] = withScope(scope, () => {
const span = getActiveSpan();
const trace = span ? spanToTraceContext(span) : getTraceContextFromScope(scope);
const dsc = span ? getDynamicSamplingContextFromSpan(span) : getDynamicSamplingContextFromScope(client, scope);
return [dsc, trace];
});
// Add trace context to check-in if available
if (traceContext) {
serializedCheckIn.contexts = {
trace: traceContext,
};
}
// Create envelope with check-in data
const envelope = createCheckInEnvelope(
serializedCheckIn,
dynamicSamplingContext,
client.getSdkMetadata(),
tunnel,
client.getDsn(),
);
// KEY DIFFERENCE: await sendEnvelope instead of fire-and-forget
// No error handling - let errors propagate to caller
await client.sendEnvelope(envelope);
return id;
}Tip: React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it.
Metadata
Metadata
Assignees
Projects
Status