# 一、异常分类
- Error:错误的基类,其他错误都继承自该类型
- EvalError:Eval函数执行异常
- RangeError:数组越界
- ReferenceError:尝试引用一个未被定义的变量时,将会抛出此异常
- SyntaxError:语法解析不合理
- TypeError:类型错误,用来表示值的类型非预期类型时发生的错误
- URIError:以一种错误的方式使用全局 URI 处理函数而产生的错误
# 二、异常捕获
- 可疑区域增加
try-catch - 全局监控 JS 异常
window.onerror - 全局监控静态资源异常监听 error 事件
- 捕获没有 catch 的 Promise 异常监听 unhandledrejection 事件
- React componentDidCatch
- Vue errorHandle
- Axios 请求同一异常处理用拦截器 interceptors
- 使用日志监控服务搜集用户错误信息
# 2.1 try-catch
- 当
finally区块定义了return,则会忽略try和catch区块内的return。 - 当
try区块出现异常,则忽略try区块内的return。
// 最终返回 ‘finally’
try {
return 'try';
} catch (e) {
return 'catch';
} finally {
return 'finally';
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2.2 全局监控JS异常
/**
* @param {String} message 错误信息
* @param {String} source 出错文件
* @param {Number} lineno 行号
* @param {Number} colno 列号
* @param {Object} error Error对象
*/
window.onerror = function handleError(message, source, lineno, colno, error) {
console.log('捕获到异常', { message, source, lineno, colno, error })
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 2.3 静态资源异常
<script>
function errorHandler(error) {
console.log("捕获到静态资源加载异常", error);
}
</script>
<script src="http://cdn.xxx.com/js/test.js" onerror="errorHandler(this)"></script>
1
2
3
4
5
6
2
3
4
5
6
<!DOCTYPE html>
<html lang="en">
<head>
<script>
window.addEventListener('error', (error) => {
console.log('捕获到异常:', error)
}, true);
</script>
</head>
<body>
<script src="http://cdn.xxx.com/js/test.js"></script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 2.4 Promise异常
window.addEventListener('unhandledrejection', (e) => {
e.preventDefault();
console.log('捕获到 promise 错误了');
console.log('错误的原因是', e.reason);
console.log('错误的对象是', e.promise);
});
Promise.reject('promise error');
new Promise((resolve, reject) => {
reject('promise error');
});
new Promise((resolve) => {
resolve();
}).then(() => {
throw 'promise error';
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 2.5 React异常
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false
};
}
componentDidCatch(error, info) {
this.setState({
hasError: true
});
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>
}
return this.props.children;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 2.6 Vue异常
Vue.config.errorHandler = (err, vm, info) => {
console.log('通过 vue errorHandler 捕获的异常');
console.log(err);
console.log(vm);
console.log(info);
}
1
2
3
4
5
6
2
3
4
5
6
# 2.7 请求异常
axios.interceptors.response.use(
function (success) {
return success;
},
function (error) {
const { response } = error;
const { status, data: { message } } = response;
if (status === 401) {
goLogin();
} else if (status === 502) {
alert(message || '系统升级中,请稍后重试试');
}
return Promise.reject(response);
}
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15