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();
},
() => {
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);