What Causes This Warning?
This warning occurs when an error is thrown in a Vue lifecycle hook, event handler, or watcher, and there’s no error handler to catch it.
The Problem
<script setup>
import { onMounted } from 'vue'
// ❌ Unhandled error in lifecycle
onMounted(() => {
throw new Error('Something went wrong')
})
// ❌ Unhandled error in event handler
function handleClick() {
throw new Error('Click handler error')
}
</script>
The Fix
Add Try-Catch
<script setup>
import { onMounted } from 'vue'
onMounted(async () => {
try {
await fetchData()
} catch (error) {
console.error('Failed to fetch:', error)
// Handle error gracefully
}
})
function handleClick() {
try {
riskyOperation()
} catch (error) {
console.error('Click error:', error)
}
}
</script>
Global Error Handler
// main.js
const app = createApp(App)
app.config.errorHandler = (err, instance, info) => {
console.error('Vue error:', err)
console.log('Component:', instance)
console.log('Error info:', info)
// Send to error tracking service
// errorTracker.captureError(err, { info })
}
app.mount('#app')
Component Error Boundary
<script setup>
import { onErrorCaptured, ref } from 'vue'
const error = ref(null)
onErrorCaptured((err, instance, info) => {
error.value = err
console.error('Captured error:', err, info)
return false // Prevent propagation
})
</script>
<template>
<div v-if="error" class="error">
Something went wrong: {{ error.message }}
</div>
<slot v-else />
</template>
Common Scenarios
Async Lifecycle Hooks
<script setup>
onMounted(async () => {
try {
const data = await api.fetchData()
items.value = data
} catch (err) {
error.value = err.message
items.value = []
}
})
</script>
Watch Errors
<script setup>
watch(source, async (newVal) => {
try {
await processValue(newVal)
} catch (err) {
console.error('Watch error:', err)
}
})
</script>
Event Handler Errors
<script setup>
async function handleSubmit() {
try {
await submitForm()
showSuccess()
} catch (err) {
showError(err.message)
}
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<!-- form content -->
</form>
</template>
Error Tracking Integration
// main.js
import * as Sentry from '@sentry/vue'
Sentry.init({
app,
dsn: 'your-dsn-here'
})
// Vue's error handler still works alongside Sentry
app.config.errorHandler = (err, instance, info) => {
Sentry.captureException(err, {
extra: { componentInfo: info }
})
}
Quick Checklist
- Wrap async operations in try-catch
- Add global error handler with
app.config.errorHandler - Use
onErrorCapturedfor component error boundaries - Log errors with context for debugging
- Consider error tracking service for production