Skip to main content

guard()

guard<T>(fn, fallback?): Promise<T | undefined>

Guards an async function with error handling and optional fallback.

πŸ’Ž Why is this a Hidden Gem?

Cleaner than try/catch. Safely executes code and provides a fallback value on failure.

WHY WRAPPING NATIVE?

We prefer to wrap this to provide a safe wrapper around Throws, allowing controlled failure handling without verbose try/catch blocks. See Design Philosophy

note

Returns undefined if no fallback is provided and the function throws.


Type Parameters​

T: T​

The return type of the function.


Parameters​

fn: () => Promise<T>​

The async function to guard.

fallback?: T | (error) => T​

Optional fallback value or function that receives the error.


Returns: Promise<T | undefined>​

Promise that resolves to the function result or fallback value.


Since​

1.1.0


Also known as​

guard (Radashi) · ❌ (Lodash, es-toolkit, Remeda, Ramda, Effect, Modern Dash, Antfu)


Example​

const result = await guard(() => riskyOperation(), 'default');

const user = await guard(() => fetchUser(), (error) => {
console.error(error);
return { id: 0, name: 'Anonymous' };
});

How it works?​

Wraps an async function with error handling and optional fallback. On success, returns the result. On error, returns the fallback value (or undefined if none provided).

Fallback Function​

The fallback can be a function that receives the error:


Use Cases​

Protect optional operations πŸ“Œβ€‹

Safely execute operations that might fail without breaking the application flow. Essential for optional features and graceful degradation.

// Safely load optional user preferences
const preferences = await guard(
async () => {
return await fetchUserPreferences(userId);
},
{
theme: "light",
language: "en",
notifications: true,
}
);

console.log("User preferences:", preferences);

Handle external service failures​

Provide fallback behavior when external services are unavailable. Critical for maintaining application functionality during service outages.

// Fallback for external weather service
const weatherData = await guard(
async () => {
return await fetchWeatherData(location);
},
(error) => {
console.warn("Weather service unavailable:", error);
return {
temperature: "N/A",
condition: "Unknown",
lastUpdated: new Date(),
};
}
);

console.log("Weather information:", weatherData);

Manage feature toggles safely​

Execute feature-specific code with safe fallbacks for disabled features. Essential for A/B testing and gradual feature rollouts.

// Safe execution of experimental features
const analyticsData = await guard(
async () => {
if (!isFeatureEnabled("advanced-analytics")) {
throw new Error("Feature disabled");
}
return await collectAdvancedAnalytics();
},
async () => {
return await collectBasicAnalytics();
}
);

console.log("Analytics collected:", analyticsData);

Implement graceful error handling​

Handle errors gracefully with meaningful fallback values. Essential for user-facing operations and error recovery.

// Safe image loading with fallback
const imageData = await guard(
async () => {
return await loadUserAvatar(userId);
},
(error) => {
console.warn("Avatar loading failed:", error);
return {
url: "/default-avatar.png",
alt: "Default Avatar",
isDefault: true,
};
}
);

displayAvatar(imageData);

Ensure data consistency​

Maintain data consistency with fallback values when primary sources fail. Critical for data integrity and application reliability.

// Safe configuration loading
const config = await guard(
async () => {
return await loadRemoteConfig();
},
(error) => {
console.error("Remote config failed, using defaults:", error);
return getDefaultConfig();
}
);

initializeApp(config);

Fallback to cached data when offline​

Serve cached content when the network request fails in a PWA. Essential for offline-first applications and progressive web apps.

const loadArticle = async (slug: string) => {
return await guard(
async () => {
const response = await fetch(`/api/articles/${slug}`);
const article = await response.json();
localStorage.setItem(`article:${slug}`, JSON.stringify(article));
return article;
},
() => {
const cached = localStorage.getItem(`article:${slug}`);
return cached ? JSON.parse(cached) : { title: "Offline", body: "Content unavailable." };
}
);
};

Copy to clipboard with fallback​

Safely use the Clipboard API with a fallback to the legacy execCommand approach. Essential for "Copy to clipboard" buttons that work across all browsers.

const copyToClipboard = async (text: string) => {
return await guard(
async () => {
await navigator.clipboard.writeText(text);
return true;
},
() => {
// Fallback for older browsers or insecure contexts
const textarea = document.createElement("textarea");
textarea.value = text;
textarea.style.position = "fixed";
textarea.style.opacity = "0";
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
return true;
}
);
};

copyButton.addEventListener("click", async () => {
const success = await copyToClipboard(codeBlock.textContent ?? "");
showToast(success ? "Copied" : "Copy failed");
});

Read clipboard content with permission fallback​

Safely read clipboard content, falling back gracefully when permission is denied. Critical for paste-from-clipboard features in editors and form fields.

const readClipboard = async () => {
return await guard(
async () => {
const text = await navigator.clipboard.readText();
return text;
},
() => {
showPastePrompt("Press Ctrl+V to paste");
return null;
}
);
};

Detect browser capabilities safely​

Check for browser API support without crashing on unsupported environments. Critical for progressive enhancement and cross-browser compatibility.

const getGeolocation = await guard(
async () => {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject, { timeout: 5000 });
});
},
() => {
console.warn("Geolocation unavailable, using default location");
return { coords: { latitude: 48.8566, longitude: 2.3522 } };
}
);

renderMap(getGeolocation.coords);