基于 TS 实现 axios(三)

本文详细介绍了如何在基于 TypeScript 的 Axios 实现中处理各种错误,包括网络错误、超时错误和其他错误。通过监听 XMLHttpRequest 的相应事件,以及检查 response.status,可以实现详尽的错误信息捕获。同时,文章提到了代码结构的调整,以更好地组织错误处理逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一小节,主要是把异常的处理加上

处理错误

网络错误

就在你发送 Ajax 请求的地方,new 出来的 XMLHttpRequest 有一个 onerror 的方法,把你的方法挂上去就可以了。

request.onerror = function handleError() {
    reject(new Error('Network Error'));
} 

超时错误

同样的,在new 出来的 XMLHttpRequest 有一个 ontimeout 的方法,把你的方法挂上去就可以了。

if(timeout) request.timeout = timeout;	// timeout 是可选的

request.ontimeout = function handleTimeout() {
    reject(new Error(`Timeout of ${timeout} ms exceeded`));
}

其他错误

response.status 在 [200,300) 之间,就表明请求成功,否则就表示错误。以下这个函数是放在 onreadystatechange 函数的最后来进行处理。

function handleResponse(response: AxiosResponse) : void{
    if(response.status >= 200 && response.status < 300) {
    	reslove(response);
    } else {
    	reject(new Error(`Request failed with status code ${response.status}`));
    }
}

更加详尽的错误信息

这个其实就是构造函数

import {AxiosRequestConfig,AxiosResponse} from '../types';

export class AxiosError extends Error {
    isAxiosError: boolean
    config: AxiosRequestConfig
    code?: string|null
    request?:any
    response?:AxiosResponse
    constructor(
        message:string,
        config:AxiosRequestConfig,
        code?: string|null,
        request?:any,
        response?: AxiosResponse,

    ){
        super(message);
        this.config = config;
        this.code = code;
        this.request = request;
        this.response = response;
        this.isAxiosError = true;
        Object.setPrototypeOf(this,AxiosError.prototype);
    }
}

export function createError(
    message:string,
    config:AxiosRequestConfig,
    code?: string|null,
    request?:any,
    response?: AxiosResponse,
) {
    return new AxiosError(message,config,code,request,response);
}

在之前使用 new Error() 的,都改成 createError 函数

完整的代码,这里只写一些改变了的代码,按照之前的目录结构,我会在 helpers 中新建立一个 error.ts 文件

import {AxiosRequestConfig,AxiosResponse} from '../types';

export class AxiosError extends Error {
    isAxiosError: boolean
    config: AxiosRequestConfig
    code?: string|null
    request?:any
    response?:AxiosResponse
    constructor(
        message:string,
        config:AxiosRequestConfig,
        code?: string|null,
        request?:any,
        response?: AxiosResponse,

    ){
        super(message);
        this.config = config;
        this.code = code;
        this.request = request;
        this.response = response;
        this.isAxiosError = true;
        Object.setPrototypeOf(this,AxiosError.prototype);
    }
}


export function createError(
    message:string,
    config:AxiosRequestConfig,
    code?: string|null,
    request?:any,
    response?: AxiosResponse,
) {
    return new AxiosError(message,config,code,request,response);
}

types/index.ts 中就添加了一个结构 AxiosError

/...
export interface AxiosError extends Error {
    isAxiosError: boolean,
    config: AxiosRequestConfig,
    code?: string | null,
    request?:any;
    response?:AxiosResponse,
}

还有 xhr.ts 改变过:

import {AxiosRequestConfig,AxiosPromise,AxiosResponse} from './types';
import {parseHeaders} from './helpers/header';
import {createError} from './helpers/error';

export default function xhr(config:AxiosRequestConfig) : AxiosPromise {
    return new Promise((reslove,reject)=> {
        const {data = null,url,method='get',timeout,headers,responseType} = config;
        const request = new XMLHttpRequest();
        
        if(responseType) request.responseType = responseType;

        // 超时操作
        if(timeout) request.timeout = timeout;
    
        request.onreadystatechange = function handleLoad() {
            if(request.readyState !== 4) {
                return;
            }

            if(request.status === 0) {
                // 网络错误和超时错误时 status为 0
                return;
            }

            const responseHeaders = request.getAllResponseHeaders();
            const responseDate = responseType !== 'text' ? request.response : request.responseText;
            const response:AxiosPromise = {
                data:responseDate,
                status:request.status,
                statusText: request.statusText,
                headers: parseHeaders(responseHeaders),
                config,
                request,
            }
            handleResponse(response);
        }

        request.open(method.toUpperCase(),url,true);
// 错误开始        
        // 请求错误
        request.onerror = function handleError() {
            reject(createError('Network Error',config,null,request));
        } 
        // 超时错误
        request.ontimeout = function handleTimeout() {
            reject(createError(`Timeout of ${timeout} ms exceeded`,config,'ECONNABORTED',request));
        }
// 错误结束        
        Object.keys(headers).forEach((name) => {
            if(data === null && name.toLocaleLowerCase() === 'content-type') {
                delete headers[name];
            }
            request.setRequestHeader(name,headers[name]);
        })

        request.send(data);

        function handleResponse(response: AxiosResponse) : void{
            if(response.status >= 200 && response.status < 300) {
                reslove(response);
            } else {
                reject(createError(`Request failed with status code ${response.status}`,config,null,request,response));
            }
        }
    })

}

现在就没有了,就到这里,之后会就是用这个 axios 方法来扩展一些方法,例如 axios.get 等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值