Implement graceful recipe error handling with filename display (#4363)

Signed-off-by: Jon Andersen <jon.andersen.se@gmail.com>
This commit is contained in:
Jon Andersen
2025-08-27 11:02:58 -04:00
committed by GitHub
parent 99fa6289c4
commit e79c7663a7
2 changed files with 86 additions and 60 deletions
+25 -2
View File
@@ -372,8 +372,10 @@ Parameters you can use:
} }
}; };
// Render a recipe item // Render a recipe item with error handling
const RecipeItem = ({ savedRecipe }: { savedRecipe: SavedRecipe }) => ( const RecipeItem = ({ savedRecipe }: { savedRecipe: SavedRecipe }) => {
try {
return (
<Card className="py-2 px-4 mb-2 bg-background-default border-none hover:bg-background-muted cursor-pointer transition-all duration-150"> <Card className="py-2 px-4 mb-2 bg-background-default border-none hover:bg-background-muted cursor-pointer transition-all duration-150">
<div className="flex justify-between items-start gap-4"> <div className="flex justify-between items-start gap-4">
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
@@ -433,6 +435,27 @@ Parameters you can use:
</div> </div>
</Card> </Card>
); );
} catch (error) {
// Error row showing failed to read file with filename and error details
return (
<Card className="py-2 px-4 mb-2 bg-red-50 border border-red-200 dark:bg-red-900/20 dark:border-red-800">
<div className="flex justify-between items-start gap-4">
<div className="min-w-0 flex-1">
<div className="flex items-center gap-2 mb-1">
<AlertCircle className="w-4 h-4 text-red-500 flex-shrink-0" />
<h3 className="text-base text-red-700 dark:text-red-300">
Failed to read file: {savedRecipe.filename}
</h3>
</div>
<p className="text-red-600 dark:text-red-400 text-sm">
{error instanceof Error ? error.message : 'Unknown error'}
</p>
</div>
</div>
</Card>
);
}
};
// Render skeleton loader for recipe items // Render skeleton loader for recipe items
const RecipeSkeleton = () => ( const RecipeSkeleton = () => (
+3
View File
@@ -12,6 +12,7 @@ export interface SavedRecipe {
isGlobal: boolean; isGlobal: boolean;
lastModified: Date; lastModified: Date;
isArchived?: boolean; isArchived?: boolean;
filename: string; // The actual filename used
} }
/** /**
@@ -66,6 +67,7 @@ async function loadRecipeFromFile(
return { return {
...recipeData, ...recipeData,
isGlobal: isGlobal, isGlobal: isGlobal,
filename: recipeName,
}; };
} catch (error) { } catch (error) {
console.warn(`Failed to load recipe from ${filePath}:`, error); console.warn(`Failed to load recipe from ${filePath}:`, error);
@@ -112,6 +114,7 @@ export async function saveRecipe(recipe: Recipe, options: SaveRecipeOptions): Pr
// Create saved recipe object // Create saved recipe object
const savedRecipe: SavedRecipe = { const savedRecipe: SavedRecipe = {
name: sanitizedName, name: sanitizedName,
filename: sanitizedName,
recipe: recipe, recipe: recipe,
isGlobal: global, isGlobal: global,
lastModified: new Date(), lastModified: new Date(),