一比一还原axios源码(三)—— 错误处理
前面的章节我们已经可以正确的处理正确的请求,并且通过处理header、body,以及加入了promise,让我们的代码更像axios了。这一章我们一起来处理ajax请求中的错误。
一、错误处理
首先我们要知道错误有哪些类型,通常我们遇到的错误有以下几种:网络错误、超时错误和非200状态码错误。其实都不复杂我们来看下:
1、网络异常
网络异常,会触发XMLHttpRequest的onerror事件,所以我们只需要加上就可以了:
request.onerror = function handleError() {
reject(new Error("Network Error"));
};
2、超时错误
XMLHttpRequest对象允许配置timeout参数,默认是0,也就是永远不会超时,所以我们的代码这样处理就可以了,注意,这里的config.timeout的config,实际上就是我们传入的配置参数,只不过这里引用了一下,包括后续的完整的实现其他api的部分,有很多其实都是对原生api的一个简单的映射和转换,后面再说:
if (config.timeout) {
request.timeout = config.timeout;
} request.ontimeout = function handleTimeout() {
reject(new Error(`Timeout of ${config.timeout} ms exceeded`));
};
3、非200状态码
如果请求报错。那么XMLHttpRequest的status属性会返回0,所以我们需要额外判断下status,中断后续的代码:
我们在onreadystatechange回调中加入status的判断。然后我们改变一下抛出response的方式,使用一个函数来处理:
return new Promise((resolve, reject) => {
var request = new XMLHttpRequest();
config.headers = processHeaders(config.headers || {}, config.data);
config.data = transformRequest(config.data);
request.open(
config.method.toUpperCase(),
buildURL(config.url, config.params, config.paramsSerializer),
true
);
request.onreadystatechange = function handleLoad() {
if (request.readyState !== 4) {
return;
}
if (request.status === 0) {
return;
}
const responseHeaders = parseHeaders(request.getAllResponseHeaders());
const responseData =
config.responseType && config.responseType !== "text"
? request.response
: request.responseText;
const response = {
data: responseData,
status: request.status,
statusText: request.statusText,
headers: responseHeaders,
config,
request,
};
handleResponse(response);
};
// 加了这个方法来集中处理response
function handleResponse(response) {
if (response.status >= 200 && response.status < 300) {
resolve(response);
} else {
reject(new Error(`Request failed with status code ${response.status}`));
}
}
很简单~~。错误处理完成到这里实际上就完成了,简单总结下,拦截了readystatechange事件中的status并根据对应的情况,处理response是resolve还是reject。然后根据timeout和error事件来抛出对应的错误。
但是到这里还没真正的完成错误的处理,因为我们在错误处理的时候仅仅抛出了错误信息,没办法处理一些额外的数据,比如请求配置、响应对象等。我们下面来完成一个Error类,集中处理这些情况,让我们的代码更健壮。
二、完成AxiosError
首先我们在core文件夹下创建一个createError文件:
export default function createError(message, config, code, request, response) {
var error = new Error(message);
return enhanceError(error, config, code, request, response);
}
我们来看上面的代码,整个createError方法,返回了报错信息、配置、状态码、请求和响应内容。然后我们实际执行返回的是enhanceError方法。我们再来在core文件夹下创建一个enhanceError文件:
export default function enhanceError(error, config, code, request, response) {
error.config = config;
if (code) {
error.code = code;
} error.request = request;
error.response = response;
error.isAxiosError = true; error.toJSON = function toJSON() {
return {
// Standard
message: this.message,
name: this.name,
// Microsoft
description: this.description,
number: this.number,
// Mozilla
fileName: this.fileName,
lineNumber: this.lineNumber,
columnNumber: this.columnNumber,
stack: this.stack,
// Axios
config: this.config,
code: this.code,
status:
this.response && this.response.status ? this.response.status : null,
};
};
return error;
}
上面的代码,很简单,把所有的信息绑定到error对象上,最后再返回error即可。其中需要注意的是,error.toJSON这个东西,它实际上做的就是当你在外层调用error的toJSON方法的时候,会返回这个更改后的方法。相当于改写了这个对象上的toJSON方法。
比如我们打印下这个东西:
console.log(
createError(timeoutErrorMessage, config, "ETIMEDOUT", request).toJSON()
);
就是enhanceError返回的那个。OK,到此我们已经写好了createError方法(其实我是从源码复制过来的,一点修改都没有)。那么我们需要修改下之前错误处理中的代码,至于具体修改的方法,就当留个作业了。大家也可以去项目中的c3分支查看。
到此,我们处理完了错误信息,添加了新的createError方法。到目前为止,其实代码都还不是真正的axios,为什么这么说呢,到现在,我们只是实现了其中的功能,但是其实还不是真正的axios源码的组织方式,我们下一章,就来扩展整个zaking-axios,修改文件的相关性,创建Axios类等,来完成更多的功能。
最新文章
- Centos7 编译安装 Nginx PHP Mariadb Memcached 扩展 ZendOpcache扩展 (实测 笔记 Centos 7.3 + Mariadb 10.1.20 + Nginx 1.10.2 + PHP 7.1.0 + Laravel 5.3 )
- [HTTP Protocol] 200 OK (from cache)和304 Not Modified
- Total Commander 常用快捷键(并附快捷键大全)
- windows下的C/C++精确计时
- [Leetcode] Remove Duplicates From Sorted Array II (C++)
- eclipse 和myEclipse 项目导入
- 从session实现机制分析模拟请求验证码的可行性(转)
- Linux上查看用户名和组并把特定用户放到特定的组之下
- day-5 python协程与I/O编程深入浅出
- 实验吧_密码忘记了(vim编辑器+代码审计)&;天网管理系统(php弱比较+反序列化)
- WPF MVVM UI分离之《交互与数据分离》
- Why Ambari is setting the security protocol of the kafka to PLAINTEXTSASL instead of SASL_PLAINTEXT?
- hbase-bloom filter
- RNN入门(三)利用LSTM生成旅游点评
- Vue开发中遇到的问题及解决方案
- Python+Selenium学习--自动生成HTML测试报告
- Alias自定义命令
- tensorflow环境下安装scikit-learn
- 非常不错的js 屏蔽类加验证类
- 阿里云服务器windows server流量不大的情况下,tomcat经常出现访问阻塞,手动ctrl+c或者点击右键又访问正常