watchdog: Handle exception in `callback`.

Earlier, in the 'check_for_unsuspend' function, we didn't
handle the exception, if any, during callback execution,
resulting in 'watchdog_time' not always being updated.

This commit handles the exception using the try/catch block.

Fixes #27723.
This commit is contained in:
Prakhar Pratyush 2023-11-19 12:02:48 +05:30 committed by Tim Abbott
parent 295b4fc337
commit c539b8ee46
2 changed files with 28 additions and 1 deletions

View File

@ -1,3 +1,5 @@
import * as blueslip from "./blueslip";
const unsuspend_callbacks: (() => void)[] = []; const unsuspend_callbacks: (() => void)[] = [];
let watchdog_time = Date.now(); let watchdog_time = Date.now();
@ -35,7 +37,17 @@ export function check_for_unsuspend(): void {
// Our app's JS wasn't running, which probably means the machine was // Our app's JS wasn't running, which probably means the machine was
// asleep. // asleep.
for (const callback of unsuspend_callbacks) { for (const callback of unsuspend_callbacks) {
callback(); try {
callback();
} catch (error) {
blueslip.error(
`Error while executing callback '${
callback.name || "Anonymous function"
}' from unsuspend_callbacks.`,
undefined,
error,
);
}
} }
} }
watchdog_time = new_time; watchdog_time = new_time;

View File

@ -6,6 +6,7 @@ const MockDate = require("mockdate");
const {set_global, zrequire} = require("./lib/namespace"); const {set_global, zrequire} = require("./lib/namespace");
const {run_test} = require("./lib/test"); const {run_test} = require("./lib/test");
const blueslip = require("./lib/zblueslip");
let time = 0; let time = 0;
let checker; let checker;
@ -58,6 +59,20 @@ run_test("basics", () => {
advance_secs(21); advance_secs(21);
watchdog.check_for_unsuspend(); watchdog.check_for_unsuspend();
assert.equal(num_times_called_back, 1); assert.equal(num_times_called_back, 1);
// Error while executing callback
num_times_called_back = 0;
advance_secs(21);
watchdog.on_unsuspend(() => {
num_times_called_back += 1;
throw new Error("Some error while executing");
});
blueslip.expect(
"error",
`Error while executing callback 'Anonymous function' from unsuspend_callbacks.`,
);
watchdog.check_for_unsuspend();
assert.equal(num_times_called_back, 2);
}); });
run_test("suspect_offline", () => { run_test("suspect_offline", () => {