一比一还原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类等,来完成更多的功能。
一比一还原axios源码(三)—— 错误处理的更多相关文章
- 一比一还原axios源码(零)—— 概要
从vue2版本开始,vue-resource就不再被vue所维护和支持,官方也推荐使用axios,所以,从我使用axios至今,差不多有四五年了,这四五年的时间只能算是熟练应用,很多内部的实现和原理不 ...
- 一比一还原axios源码(四)—— Axios类
axios源码的分析,到目前为止,算上第0章已经四章了,但是实际上,还都没有进入axios真正的主线,我们来简单回顾下.最开始我们构建了get请求,写了重要的buildURL方法,然后我们处理请求体请 ...
- 一比一还原axios源码(一)—— 发起第一个请求
上一篇文章,我们简单介绍了XMLHttpRequest及其他可以发起AJAX请求的API,那部分大家有兴趣可以自己去扩展学习.另外,简单介绍了怎么去读以及我会怎么写这个系列的文章,那么下面就开始真正的 ...
- 一比一还原axios源码(六)—— 配置化
上一章我们完成了拦截器的代码实现,这一章我们来看看配置化是如何实现的.首先,按照惯例我们来看看axios的文档是怎么说的: 首先我们可以可以通过axios上的defaults属性来配置api. 我们可 ...
- 一比一还原axios源码(八)—— 其他功能
到此,我们完成了axios的绝大部分的功能,接下来我们来补全一下其他的小功能. 一.withCredentials 这个参数可以可以表明是否是一个跨域的请求.那这个的使用场景是啥呢?就是我们在同域的 ...
- 一比一还原axios源码(五)—— 拦截器
上一篇,我们扩展了Axios,构建了一个Axios类,然后通过这个Axios工厂类,创建真正的axios实例.那么今天,我们来实现下Axios的拦截器也就是interceptors.我们来简单看下Ax ...
- 一比一还原axios源码(二)—— 请求响应处理
上一章,我们开发了一些简单的代码,这部分代码最最核心的一个方法就是buildURL,应对了把对象处理成query参数的方方面面.虽然我们现在可以发起简单的请求了,但是第一,我们无法接收到服务器的响应, ...
- axios源码解析 - 请求拦截器
axios请求拦截器,也就是在请求发送之前执行自定义的函数. axios源码版本 - ^0.27.2 (源码是精简版) 平时在业务中会这样去写请求拦截器,代码如下: // 创建一个新的实例 var s ...
- Axios源码深度剖析 - 替代$.ajax,成为xhr的新霸主
前戏 在正式开始axios讲解前,让我们先想想,如何对现有的$.ajax进行简单的封装,就可以直接使用原声Promise了? let axios = function(config){ return ...
随机推荐
- java-swing-事件监听-焦点监听器
感谢大佬:https://blog.csdn.net/weixin_44512194/article/details/93377551 开始不知道焦点是啥,其实就是打字的时候,这个一闪一闪的竖线. 与 ...
- VC 获取当前运行窗口名称
转载请注明来源:https://www.cnblogs.com/hookjc/ BOOL CALLBACK WindowChild(HWND hwnd,LPARAM lparam){ CFGDlg* ...
- Java&Tomcat环境变量配置
版本匹配: Java PATH环境变量.作用是指定命令搜索路径,在shell下面执行命令时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序.我们需要把 jdk安装目录下的bin目录增加 ...
- 解决Wordpress提示FTP登录问题
向wordpress目录的wordpress-config.php中添加 define("FS_METHOD", "direct"); define(" ...
- Javascript 生成全局唯一标识符 (GUID,UUID)
全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) . GUID是一种由算法生成的二进制长度 ...
- Class.getResource和ClassLoader.getResource的路径写法
Java中取资源时,经常用到Class.getResource和ClassLoader.getResource,这里来看看他们在取资源文件时候的路径问题. Class.getResource(Stri ...
- oracle查看当前正在使用的数据库
select name from V$DATABASE; 也可以用 select SYS_CONTEXT('USERENV','INSTANCE_NAME') from dual;
- iOS App 架构文章推荐
iOS应用开发架构 iOS应用架构谈系列 阿里技术沙龙 2.2.1. Hybrid App 2.2.2. taobao 客户端架构 2.2.3. alipay 客户端架构 iOS APP 架构漫谈 ...
- 宝塔面板部署springboot项目并使用域名访问
环境准备:服务器搭建宝塔linux面板项目: springboot项目项目打包方式jar包 环境: 一.服务器,一个域名,然后再服务器上(DNS服务)将域名解析好.把安全组设置好. 二.用宝塔快速搭建 ...
- PHP爱考的那些笔试题
PHP爱考的那些笔试题 来自<PHP程序员面试笔试宝典>,涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书. 一.单例模式是在应用程序中最多只能拥有 ...