ADR-011: Dynamic Route Error Handling
Status
Section titled “Status”Accepted
Context
Section titled “Context”Dynamic routes in Astro (e.g., /blog/[slug].astro) use getStaticPaths() to generate pages at build time. While Astro’s static path generation prevents most runtime errors, edge cases can still occur:
- Development errors: Props may be undefined during development/testing
- Build-time issues: Content collection queries could fail or return unexpected data
- Future refactoring: Changes to data structures might introduce undefined states
- Defensive programming: Following fail-safe principles for production resilience
Without explicit error handling, these edge cases result in:
- Cryptic build failures
- Poor developer experience during debugging
- Potential runtime errors if SSR is ever enabled
Decision
Section titled “Decision”Implement defensive error handling in all dynamic route files with:
- Undefined post check: Redirect to 404 if post data is missing
- Slug mismatch validation: Handle cases where post slug doesn’t match URL parameter
- Boundary condition comments: Document null handling for prev/next navigation
- Early returns: Use Astro’s redirect for graceful failure
Implementation Pattern
Section titled “Implementation Pattern”const { post } = Astro.props;
// Error handling: Redirect to 404 if post is undefinedif (!post) { return Astro.redirect("/404");}
// ... fetch related data ...
const currentIndex = allPosts.findIndex((p) => p.slug === post.slug);
// Edge case: If slug mismatch (should not happen with static paths, but defensive)if (currentIndex === -1) { return Astro.redirect("/404");}
// Get previous and next posts (null if at boundaries)const prevPost = currentIndex > 0 ? allPosts[currentIndex - 1] : null;const nextPost = currentIndex < allPosts.length - 1 ? allPosts[currentIndex + 1] : null;Rationale
Section titled “Rationale”Why This Approach?
Section titled “Why This Approach?”- Fail-safe design: Gracefully handles unexpected states rather than crashing
- Developer experience: Clear error messages via 404 page instead of build failures
- Production resilience: Prevents edge cases from breaking the entire site
- Future-proof: Protects against refactoring errors or data structure changes
- Minimal overhead: Zero runtime cost for static builds (checks happen at build time)
Why Not Alternative Approaches?
Section titled “Why Not Alternative Approaches?”Alternative 1: Throw errors
if (!post) throw new Error("Post not found");❌ Breaks build process, poor user experience
Alternative 2: Silent fallback
const post = Astro.props.post ?? defaultPost;❌ Masks bugs, creates confusing behavior
Alternative 3: No error handling
const { post } = Astro.props; // Trust getStaticPaths❌ Fragile during development, no safety net
Consequences
Section titled “Consequences”Positive
Section titled “Positive”- ✅ Resilience: Graceful degradation for edge cases
- ✅ DX: Clear 404 pages instead of cryptic build errors
- ✅ Maintainability: Explicit error handling documents assumptions
- ✅ Debugging: Easier to trace issues with explicit checks
- ✅ Zero cost: No runtime overhead for static builds
Neutral
Section titled “Neutral”- Slightly more verbose code (4-6 extra lines per dynamic route)
- Requires consistent application across all dynamic routes
Negative
Section titled “Negative”- None identified - this is a pure improvement following defensive programming principles
Compliance
Section titled “Compliance”- User Rules: ✅ Follows minimal, focused edits principle
- User Rules: ✅ Uses comments to document edge cases
- User Rules: ✅ Implements defensive programming without over-engineering
- Performance: ✅ Zero runtime overhead (build-time only)
- Accessibility: ✅ Redirects to proper 404 page with ARIA labels
Implementation Checklist
Section titled “Implementation Checklist”Apply this pattern to all dynamic routes:
-
/src/pages/blog/[slug].astro -
/src/pages/projects/[slug].astro(if applicable) - Any future dynamic routes
Related Files
Section titled “Related Files”src/pages/blog/[slug].astro- Primary implementationsrc/pages/404.astro- Error destinationsrc/layouts/BlogLayout.astro- Handles null prev/next gracefully
Future Considerations
Section titled “Future Considerations”- Monitor build logs for 404 redirects (indicates data issues)
- Consider adding build-time validation for content collections
- If SSR is enabled, add runtime error logging
- Add integration tests for error handling paths
References
Section titled “References”- Astro Dynamic Routes
- Astro Redirects
- Defensive Programming Principles
Enforcement
Section titled “Enforcement”- Not machine-checkable: presence of the defensive redirect pattern in dynamic routes is a review concern. A grep-based check was evaluated during the enforcement retrofit and rejected as brittle (pattern text varies legitimately); see ADR-064.
- Graduation log: (empty at creation; entries added when a check changes status)
Date: 2025-10-01 (footer backfilled 2026-07-05 from git history; this record predates the footer convention)
Participants: Template maintainers
Outcome: Accepted