Skip to content

Instantly share code, notes, and snippets.

@stevekrouse
Created February 16, 2025 00:11
Show Gist options
  • Save stevekrouse/ae840767e1a56f2bb1623401feb98d02 to your computer and use it in GitHub Desktop.
Save stevekrouse/ae840767e1a56f2bb1623401feb98d02 to your computer and use it in GitHub Desktop.
Find the bug
import { email } from "https://esm.town/v/std/email?v=13";
const MAX_TRIES = 3;
export async function uptimeCheck(url: string, attempt = 1) {
let ok = true;
try {
const res = await fetch(url);
if (res.status === 200) {
console.log(`Website up (${url})`);
} else {
ok = false;
}
} catch (e) {
ok = false;
}
if (!ok) {
if (attempt < MAX_TRIES) {
console.log(`${url} down, attempt ${attempt}, retrying...`);
return uptimeCheck(url, attempt + 1);
} else {
console.log(`${url} down, attempt ${attempt}, notifying...`);
await email({ subject: `Website down (${url})` });
}
}
}
const urls = [
"https://www.google.com",
"https://www.youtube.com",
"https://www.biasdfafng.com",
];
await Promise.all(
urls.map(uptimeCheck),
);
=====================
There's a bug in how the function handles the return value during recursive retries. Here's the issue and fix:
The function doesn't return a value in the success case (when `ok` is true), which means it returns `undefined`. In the retry case, while it returns the recursive call to `uptimeCheck`, this value isn't being used or propagated up.
Here's the corrected version:
```typescript
import { email } from "https://esm.town/v/std/email?v=13";
const MAX_TRIES = 3;
export async function uptimeCheck(url: string, attempt = 1) {
let ok = true;
try {
const res = await fetch(url);
if (res.status === 200) {
console.log(`Website up (${url})`);
return true; // Add explicit return for success case
} else {
ok = false;
}
} catch (e) {
ok = false;
}
if (!ok) {
if (attempt < MAX_TRIES) {
console.log(`${url} down, attempt ${attempt}, retrying...`);
return uptimeCheck(url, attempt + 1);
} else {
console.log(`${url} down, attempt ${attempt}, notifying...`);
await email({ subject: `Website down (${url})` });
return false; // Add explicit return for failure case
}
}
}
const urls = [
"https://www.google.com",
"https://www.youtube.com",
"https://www.biasdfafng.com",
];
await Promise.all(
urls.map(uptimeCheck),
);
```
The main changes made:
1. Added `return true` in the success case when status is 200
2. Added `return false` after sending the email in the failure case
Without these explicit returns, the function could return `undefined` in some cases, which makes it harder to track the actual status of each check. Now the function will consistently return a boolean indicating whether the check ultimately succeeded or failed.
This is important because Promise.all() is being used to run these checks in parallel, and having proper return values makes it easier to handle and track the results if needed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment