ErrorTypes Enumeration | Vue Router
ErrorTypes is an enumeration that defines various error types that can occur during router operations. This enum helps categorize and handle different types of routing errors consistently. 🚨
📋 Enum Definition
enum ErrorTypes {
MATCHER_NOT_FOUND = 1,
NAVIGATION_GUARD_REDIRECT = 2,
NAVIGATION_ABORTED = 4,
NAVIGATION_CANCELLED = 8,
NAVIGATION_DUPLICATED = 16
}🎯 Purpose and Usage
The ErrorTypes enumeration provides a standardized way to identify and handle different categories of routing errors. Each error type corresponds to specific failure scenarios in the routing system.
Key Benefits:
- ✅ Error Categorization - Classifies errors into meaningful categories
- ✅ Consistent Handling - Enables uniform error handling patterns
- ✅ Debugging Support - Helps identify root causes of routing issues
- ✅ Type Safety - Provides TypeScript support for error handling
🔍 Enumeration Members
MATCHER_NOT_FOUND - Route Matcher Error
Value: 1
This error occurs when the router cannot find a matching route for the requested path. It typically indicates that the route configuration is missing or incorrect.
Common Scenarios:
- Navigating to a non-existent route
- Route configuration errors
- Dynamic route parameter mismatches
Example:
try {
await router.push('/non-existent-route')
} catch (error) {
if (error.type === ErrorTypes.MATCHER_NOT_FOUND) {
console.error('Route not found:', error.to.path)
// Handle 404 scenario
showNotFoundPage()
}
}NAVIGATION_GUARD_REDIRECT - Guard Redirect Error
Value: 2
This error type represents redirects initiated by navigation guards. While technically an "error" in the navigation flow, it's a normal part of guard-based redirects.
Common Scenarios:
- Authentication guards redirecting to login
- Permission-based redirects
- Conditional routing logic
Example:
router.beforeEach((to, from) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
// This creates a NAVIGATION_GUARD_REDIRECT error
return '/login'
}
})
// Handling guard redirects
router.push('/protected').catch(error => {
if (error.type === ErrorTypes.NAVIGATION_GUARD_REDIRECT) {
console.log('Redirected by guard to:', error.to.path)
// This is expected behavior, not an actual error
}
})Navigation Failure Types (4, 8, 16)
These values correspond to the NavigationFailureType enumeration and represent specific navigation failure scenarios:
NAVIGATION_ABORTED(4) - Navigation was aborted by a guardNAVIGATION_CANCELLED(8) - Navigation was cancelled by a subsequent navigationNAVIGATION_DUPLICATED(16) - Navigation to the current location was attempted
Note: These are maintained for backward compatibility but NavigationFailureType should be used for navigation-specific errors.
💡 Practical Error Handling
Comprehensive Error Handler
function setupGlobalErrorHandler(router: Router) {
router.onError((error) => {
console.group('Router Error Details')
console.log('Error type:', error.type)
console.log('Error message:', error.message)
console.log('Target route:', error.to)
console.log('From route:', error.from)
console.groupEnd()
// Handle different error types
switch (error.type) {
case ErrorTypes.MATCHER_NOT_FOUND:
handleRouteNotFound(error)
break
case ErrorTypes.NAVIGATION_GUARD_REDIRECT:
handleGuardRedirect(error)
break
case ErrorTypes.NAVIGATION_ABORTED:
case ErrorTypes.NAVIGATION_CANCELLED:
case ErrorTypes.NAVIGATION_DUPLICATED:
handleNavigationFailure(error)
break
default:
handleUnknownError(error)
}
})
}Route-Specific Error Handling
async function navigateSafely(targetRoute: string) {
try {
await router.push(targetRoute)
console.log('Navigation completed successfully')
} catch (error) {
if (error.type === ErrorTypes.MATCHER_NOT_FOUND) {
// Fallback to a known route
await router.push('/fallback')
showErrorMessage(`Route ${targetRoute} not found`)
} else if (error.type === ErrorTypes.NAVIGATION_ABORTED) {
// Handle aborted navigation (e.g., permission denied)
showAccessDeniedMessage()
} else {
// Generic error handling
console.error('Navigation error:', error)
showGenericError()
}
}
}🔧 Advanced Error Management
Error Recovery Strategies
class ErrorRecoveryService {
private retryAttempts = new Map<string, number>()
async navigateWithRetry(to: RouteLocationRaw, maxRetries = 3): Promise<void> {
const routeKey = JSON.stringify(to)
let attempts = this.retryAttempts.get(routeKey) || 0
try {
await router.push(to)
this.retryAttempts.delete(routeKey) // Clear on success
} catch (error) {
attempts++
this.retryAttempts.set(routeKey, attempts)
if (attempts <= maxRetries) {
console.log(`Retry attempt ${attempts} for route:`, to)
await this.delay(1000 * attempts) // Exponential backoff
return this.navigateWithRetry(to, maxRetries)
} else {
this.handleMaxRetriesExceeded(error, to)
}
}
}
private handleMaxRetriesExceeded(error: any, to: RouteLocationRaw) {
switch (error.type) {
case ErrorTypes.MATCHER_NOT_FOUND:
this.handlePermanentRouteError(to)
break
case ErrorTypes.NAVIGATION_ABORTED:
this.showPermanentAccessDenied()
break
default:
this.showGenericRetryError()
}
}
}Error Analytics and Reporting
class ErrorAnalytics {
trackRouterError(error: any, context: NavigationContext) {
const errorData = {
type: error.type,
message: error.message,
route: context.to.path,
timestamp: Date.now(),
userAgent: navigator.userAgent,
// Additional context
fromRoute: context.from?.path,
navigationType: context.navigationType
}
// Send to analytics service
analytics.track('router_error', errorData)
// Log for debugging
if (process.env.NODE_ENV === 'development') {
console.error('Router Error:', errorData)
}
}
setupErrorTracking(router: Router) {
router.onError((error) => {
this.trackRouterError(error, {
to: error.to,
from: error.from,
navigationType: 'programmatic'
})
})
}
}🚨 Important Considerations
Error Type Compatibility
import { ErrorTypes, NavigationFailureType } from 'vue-router'
// ✅ Correct - use appropriate enum for the context
if (error.type === ErrorTypes.MATCHER_NOT_FOUND) {
// Handle route matching errors
}
if (error.type === NavigationFailureType.ABORTED) {
// Handle navigation failures
}
// ❌ Avoid - mixing error type systems
if (error.type === 4) {
// Use named constants instead of magic numbers
}
// ✅ Better - use named constants
if (error.type === NavigationFailureType.ABORTED) {
// Clear intent
}Error Object Structure
// Typical error object structure
interface RouterError {
type: ErrorTypes | NavigationFailureType
message: string
to: RouteLocationNormalized
from?: RouteLocationNormalized
// Additional properties may be present depending on error type
}
// Example error handling with type checking
function handleRouterError(error: unknown) {
if (isRouterError(error)) {
switch (error.type) {
case ErrorTypes.MATCHER_NOT_FOUND:
// Handle specific error type
break
// ... other cases
}
} else {
// Handle non-router errors
console.error('Non-router error:', error)
}
}
function isRouterError(error: unknown): error is RouterError {
return typeof error === 'object' && error !== null && 'type' in error
}🔗 Related APIs
NavigationFailureType- Specific navigation failure typesisNavigationFailure()- Check if error is a navigation failure- Router Error Handling - Global error handling patterns
📚 Best Practices
1. Graceful Error Handling
// Instead of letting errors crash the app
router.push('/target').catch(error => {
// Provide user-friendly feedback based on error type
if (error.type === ErrorTypes.MATCHER_NOT_FOUND) {
showNotFoundMessage()
} else if (error.type === ErrorTypes.NAVIGATION_ABORTED) {
showAccessDeniedMessage()
} else {
showGenericErrorMessage()
}
})2. Development vs Production
function setupErrorHandling(router: Router) {
if (process.env.NODE_ENV === 'development') {
// Detailed error logging for development
router.onError((error) => {
console.error('Router Error Details:', {
type: error.type,
message: error.message,
stack: error.stack,
to: error.to,
from: error.from
})
})
} else {
// User-friendly error handling for production
router.onError((error) => {
// Send to error reporting service
errorReporting.captureException(error)
// Show user-friendly message
showErrorToast('Navigation failed. Please try again.')
})
}
}3. Error Recovery Patterns
class NavigationRecovery {
private fallbackRoutes = new Map<string, string>()
constructor(private router: Router) {
this.setupFallbackRoutes()
}
private setupFallbackRoutes() {
// Define fallback routes for common errors
this.fallbackRoutes.set('/admin', '/access-denied')
this.fallbackRoutes.set('/premium', '/upgrade-required')
}
async navigateWithFallback(to: RouteLocationRaw) {
try {
await router.push(to)
} catch (error) {
if (error.type === ErrorTypes.NAVIGATION_ABORTED) {
const fallback = this.fallbackRoutes.get(typeof to === 'string' ? to : to.path)
if (fallback) {
await router.push(fallback)
} else {
this.handleGenericError(error)
}
} else {
this.handleGenericError(error)
}
}
}
}💡 Pro Tip: While
ErrorTypesprovides valuable error categorization, most applications should focus on handling the specific error scenarios that matter to their users rather than trying to handle every possible error type.