【Ts重構Axios】關於處理請求error三種情況


三種錯誤描述及基本解決方案

1.錯誤網絡異常錯誤

當網絡出現異常(比如網絡不通)的時候,發送請求會觸發XMLHTTPRequest對象實例的error事件。於是,我們可以在onerror的事件回調函數中捕獲此類錯誤。

我們在xhr.ts中添加如下代碼:

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

 

2. 處理超時錯誤

我們可以設置某個請求的超時時間timeout,也就是當請求發送后超過某個時間仍然沒有收到相應,則請求自動終止,並觸發timeout事件。

請求默認的超時時間是0,即永不超時,所以我們首先需要允許程序可以配置超時時間:

export interface AxiosRequestConfig {
    // ...
    timeout?: number
}

接着在xhr函數中添加如下代碼:

const { /**...*/ timeout } = config

if (timeout) {
    request.timeout = timeout
}

request.ontimeout = function handleTimeout() {
    reject(new Error('Timeout error'))
}

 

3. 狀態碼錯誤

對於狀態碼不在200-300之間的,進行錯誤反饋

function handleResponse(response: AxiosResponse): void {
    // 錯誤情況3: 狀態碼錯誤
    if (response.status >= 200 && response.status < 300) {
        resolve(response)
    } else {
        reject(new Error(`Request failed with the code ${response.status}`))
    }
}

 

錯誤信息增強

上述,我們能處理常見的異常錯誤情況,並接收到返回的錯誤信息。但是,我們可能還希望能接收到更多的錯誤信息,比如request的信息等等。

// 舉個栗子,我們能在請求回調中,拿到更多錯誤信息,並進行分析
axios({
    method: 'get',
    url: '/error/timeout',
    timeout: 2000
}).then(res => {
    console.log(res)
}).catch((e: AxiosError) => {
    console.log(e.message)
    console.log(e.request)
    console.log(e.code)
})

這樣,我們就可以收集到更多的錯誤信息,並進一步做相應的處理,針對上述這個栗子,我們開始繼續升級

1. 創建AxiosError類

我們首先定義AxiosError類型接口,用於外部使用
types/index.ts

export interface AxiosError extends Error {
    config: AxiosRequestConfig
    code?: string
    request?: any
    response?: AxiosResponse
    isAxiosError: boolean
}

接着,我們創建error.ts文件,然后實現AxiosError類,它是集成於Error類。注意:接下來會有個坑,欲了解詳情請點擊查看我的另外一篇文章

/** 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

        /** 解決ts集成Error 等的一個坑 */
        Object.setPrototypeOf(this, AxiosError.prototype)
    }
}

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

最后,我們增強上面3個錯誤方法解決方案

...
    // 錯誤情況1: 網絡錯誤
    request.onerror = function handleError() {
        reject(createError('Network error', config, null, request))
    }

    // 錯誤情況2: 超時錯誤
    request.ontimeout = function handleTimeout() {
      reject(createError(`Timeout of ${timeout} error`, config, 'ECONNABORTED', request))
    }
    
    // 錯誤情況3: 狀態碼錯誤
    function handleResponse(response: AxiosResponse): void {
    if (response.status >= 200 && response.status < 300) {
        resolve(response)
    } else {
        reject(
            createError(
                `Request failed with the code ${response.status}`,
                config,
                null,
                request,
                response
           )
        )
    }
...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM