Promise中错误监测
前端错误收集方式
Vue中错误
Vue 全局错误处理器 app.config.errorHandler
详解
🔧 app.config.errorHandler
详解
📌 定义
app.config.errorHandler
是 Vue 应用实例的配置项之一,允许开发者定义一个函数来处理应用中的未捕获错误。
⚙️ 参数
该函数接受三个参数:
err
: 错误对象。instance(vm)
: 发生错误的组件实例。info
: 一个字符串,指示错误的来源类型
,例如:组件渲染、事件处理器、生命周期钩子等。(cn.vuejs.org, 博客园, ByteNote)
🧩 错误来源类型
app.config.errorHandler
可以捕获以下来源的错误:
- 组件渲染器
- 事件处理器
- 生命周期钩子
setup()
函数- 侦听器
- 自定义指令钩子
- 过渡 (Transition) 钩子
📝 示例代码
import { createApp } from 'vue';const app = createApp(App);app.config.errorHandler = (err, instance, info) => {console.error('全局错误处理:', err);console.log('发生错误的组件实例:', instance);console.log('错误信息:', info);
};:contentReference[oaicite:45]{index=45}
在这个示例中,当应用中发生未捕获的错误时,errorHandler
会被调用,打印错误信息。
🧪 Vue 中的错误示例
以下是一些常见的错误示例,展示了在不同场景下可能发生的错误:
1. 组件渲染器错误
在组件的模板中使用未定义的变量:(DevPress)
<template><div>{{ undefinedVariable }}</div>
</template>:contentReference[oaicite:55]{index=55}
这会导致渲染错误,errorHandler
中的 info
参数为 'render function'
。
2. 事件处理器错误
在事件处理函数中抛出错误:
<template><button @click="handleClick">点击</button>
</template><script>
export default {methods: {handleClick() {throw new Error('事件处理器错误');}}
};
</script>:contentReference[oaicite:65]{index=65}
此时,errorHandler
中的 info
参数为 'event handler'
。
3. 生命周期钩子错误
在生命周期钩子中抛出错误:(blog.dselegent.icu)
<script>
export default {mounted() {throw new Error('mounted 钩子错误');}
};
</script>:contentReference[oaicite:75]{index=75}
此时,errorHandler
中的 info
参数为 'mounted hook'
。
4. setup()
函数错误
在 setup()
函数中抛出错误:
<script setup>
throw new Error('setup 函数错误');
</script>:contentReference[oaicite:85]{index=85}
此时,errorHandler
中的 info
参数为 'setup function'
。
5. 侦听器错误
在侦听器中抛出错误:(cn.vuejs.org)
<script setup>
import { ref, watch } from 'vue';const count = ref(0);watch(count, () => {throw new Error('侦听器错误');
});
</script>:contentReference[oaicite:95]{index=95}
此时,errorHandler
中的 info
参数为 'watcher callback'
。
6. 自定义指令钩子错误
在自定义指令的钩子函数中抛出错误:(cn.vuejs.org)
<script setup>
const vColor = {mounted(el) {throw new Error('自定义指令钩子错误');}
};
</script><template><p v-color>文本</p>
</template>:contentReference[oaicite:105]{index=105}
此时,errorHandler
中的 info
参数为 'directive hook'
。
7. 过渡 (Transition) 钩子错误
在过渡钩子中抛出错误:(blog.dselegent.icu)
<script setup>
import { ref } from 'vue';const show = ref(false);function onEnter(el, done) {throw new Error('过渡钩子错误');
}
</script><template><button @click="show = !show">切换</button><Transition @enter="onEnter"><p v-if="show">内容</p></Transition>
</template>:contentReference[oaicite:115]{index=115}
此时,errorHandler
中的 info
参数为 'transition hook'
。
通过上述示例,可以更好地理解 app.config.errorHandler
的作用以及如何在不同场景下捕获和处理错误。
在 React 中,错误边界(Error Boundaries) 是一种机制,允许你捕获其子组件树中 JavaScript 错误,记录这些错误,并显示回退 UI,而不是渲染崩溃的组件树。
React中错误
🔍 什么是错误边界?
错误边界是 React 组件,它可以捕获其子组件树中发生的 JavaScript 错误,并渲染备用 UI,而不是崩溃的组件树。 (掘金)
⚙️ 如何实现错误边界?
要创建一个错误边界组件,你需要定义一个类组件,并实现以下生命周期方法之一或两者:
static getDerivedStateFromError(error)
:在渲染过程中抛出错误后调用,用于更新 state,以显示回退 UI。componentDidCatch(error, errorInfo)
:在捕获到错误后调用,可用于记录错误信息。
示例代码:
class ErrorBoundary extends React.Component {constructor(props) {super(props);this.state = { hasError: false };}static getDerivedStateFromError(error) {// 更新 state,以触发回退 UIreturn { hasError: true };}componentDidCatch(error, errorInfo) {// 可以将错误信息记录到错误报告服务logErrorToMyService(error, errorInfo);}render() {if (this.state.hasError) {// 自定义回退 UIreturn <h1>出现了错误。</h1>;}return this.props.children; }
}
使用方式:
<ErrorBoundary><MyComponent />
</ErrorBoundary>
🚫 错误边界无法捕获的错误
需要注意的是,错误边界无法捕获以下类型的错误:
- 事件处理器中的错误
- 异步代码中的错误(例如
setTimeout
或requestAnimationFrame
回调) - 服务端渲染中的错误
- 错误边界自身抛出的错误
对于这些情况,建议使用 try...catch
语句进行错误处理。
🛠️ 处理异步错误的策略
由于错误边界无法捕获异步代码中的错误,因此需要在异步操作中手动处理错误。例如,在 useEffect
中处理异步错误:
function MyComponent() {const [error, setError] = useState(null);useEffect(() => {asyncFunction().catch(err => setError(err));}, []);if (error) {// 可以选择抛出错误,让上层的错误边界捕获throw error;}return <div>内容</div>;
}
这种方式允许你在异步操作失败时,将错误传递给错误边界进行统一处理。
📦 使用第三方库:react-error-boundary
为了更方便地处理错误边界,可以使用第三方库 react-error-boundary
。该库提供了更强大的功能,如重试机制、错误日志记录等。(阿里云开发者社区)
安装:
npm install --save react-error-boundary
示例代码:
import { ErrorBoundary } from 'react-error-boundary';function ErrorFallback({ error, resetErrorBoundary }) {return (<div role="alert"><p>发生了错误:</p><pre>{error.message}</pre><button onClick={resetErrorBoundary}>重试</button></div>);
}function App() {return (<ErrorBoundaryFallbackComponent={ErrorFallback}onReset={() => {// 重置应用状态}}><MyComponent /></ErrorBoundary>);
}
该库还提供了 useErrorHandler
钩子,用于在函数组件中捕获错误。
✅ 最佳实践
- 局部与全局错误边界:根据需要,在应用的不同层级使用错误边界。例如,在顶层使用全局错误边界捕获整个应用的错误,在特定组件周围使用局部错误边界捕获特定部分的错误。
- 友好的回退 UI:为用户提供清晰、友好的错误提示,而不是显示空白页面。
- 错误日志记录:将错误信息记录到日志或发送到错误监控服务,便于后续分析和修复。
- 处理异步错误:在异步操作中使用
try...catch
语句,或在useEffect
中捕获并处理错误。 - 避免错误边界自身出错:确保错误边界组件本身的稳定性,避免其自身抛出错误。
通过以上策略,可以有效地监测和处理 React 应用中的错误,提高应用的稳定性和用户体验。