Skip to content

Commit 8e07c24

Browse files
committed
Log outputGate broken shouldRetryCountsAgainstLimits for alarms. Force exceeded memory overloaded error to be treated as user error
1 parent d21c3b8 commit 8e07c24

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

src/workerd/api/global-scope.c++

+22-10
Original file line numberDiff line numberDiff line change
@@ -471,16 +471,28 @@ kj::Promise<WorkerInterface::AlarmResult> ServiceWorkerGlobalScope::runAlarm(kj:
471471
!jsg::isDoNotLogException(desc) && context.isOutputGateBroken()) {
472472
LOG_NOSENTRY(ERROR, "output lock broke during alarm execution", actorId, e);
473473
} else if (context.isOutputGateBroken()) {
474-
// We don't usually log these messages, but it's useful to know the real reason we failed
475-
// to correctly investigate stuck alarms.
476-
LOG_NOSENTRY(ERROR,
477-
"output lock broke during alarm execution without an interesting error description",
478-
actorId, e);
474+
if (e.getType() == kj::Exception::Type::OVERLOADED) {
475+
// This is a bit hackish, but we know for a fact that this specific exception detail is
476+
// caused by user error, but not all overloaded exceptions are user fault. As such
477+
// let's treat this special case.
478+
// TODO(soon): Get a more robust way to process user errors comming from JSG exceptions.
479+
if (e.getDescription() ==
480+
"overloaded: jsg.Error: Durable Object's isolate exceeded its memory limit and was"
481+
" reset.") {
482+
shouldRetryCountsAgainstLimits = true;
483+
}
484+
}
479485
if (e.getDetail(jsg::EXCEPTION_IS_USER_ERROR) != kj::none) {
480486
// The handler failed because the user overloaded the object. It's their fault, we'll not
481487
// retry forever.
482488
shouldRetryCountsAgainstLimits = true;
483489
}
490+
491+
// We don't usually log these messages, but it's useful to know the real reason we failed
492+
// to correctly investigate stuck alarms.
493+
LOG_NOSENTRY(ERROR,
494+
"output lock broke during alarm execution without an interesting error description",
495+
actorId, e, shouldRetryCountsAgainstLimits);
484496
}
485497
return WorkerInterface::AlarmResult{.retry = true,
486498
.retryCountsAgainstLimit = shouldRetryCountsAgainstLimits,
@@ -511,16 +523,16 @@ kj::Promise<WorkerInterface::AlarmResult> ServiceWorkerGlobalScope::runAlarm(kj:
511523
LOG_NOSENTRY(ERROR, "output lock broke after executing alarm", actorId, e);
512524
}
513525
} else {
514-
// We don't usually log these messages, but it's useful to know the real reason we failed
515-
// to correctly investigate stuck alarms.
516-
LOG_NOSENTRY(ERROR,
517-
"output lock broke after executing alarm without an interesting error description",
518-
actorId, e);
519526
if (e.getDetail(jsg::EXCEPTION_IS_USER_ERROR) != kj::none) {
520527
// The handler failed because the user overloaded the object. It's their fault, we'll not
521528
// retry forever.
522529
shouldRetryCountsAgainstLimits = true;
523530
}
531+
// We don't usually log these messages, but it's useful to know the real reason we failed
532+
// to correctly investigate stuck alarms.
533+
LOG_NOSENTRY(ERROR,
534+
"output lock broke after executing alarm without an interesting error description",
535+
actorId, e, shouldRetryCountsAgainstLimits);
524536
}
525537
return WorkerInterface::AlarmResult{.retry = true,
526538
.retryCountsAgainstLimit = shouldRetryCountsAgainstLimits,

0 commit comments

Comments
 (0)