美文网首页
3-1、处理异常情况

3-1、处理异常情况

作者: Eileen_1d88 | 来源:发表于2019-12-05 15:37 被阅读0次
    需求

    之前的内容,我们完成了ts-axios的基础功能,但目前为止,我们都是处理的正常接收请求的情况,这对于一个程序的健壮性是远远不够的,所以这里我们要考虑异常情况的处理.
    并且我们也希望能捕获到这些错误,以便做进一步的处理

    axios({
      method: 'get',
      url: '/error/get'
    }).then((res) => {
      console.log(res)
    }).catch((e) => {
      console.log(e)
    })
    

    如果在请求的过程中发生了任何错误,我们都可以在reject回调函数中捕获到。
    我们把错误分为以下几类:

    • 网络异常
      当网络出现异常(比如不通)的时候,发送请求会触发XMLHttpRequest对象实例的onerror事件,所以我们可以在onerror事件的回调函数中捕获这类错误,我们在xhr函数中添加如下代码:
    request.onerror = function handleError() {
        reject(new Error('Network Error'))
    }
    
    • 超时问题处理
      我们可以设置某个请求的超时时间timeout,也就是当请求发送后超过某个时间后仍没有收到响应,则请求自动终止,并触发timeout事件。
      请求的默认超时时间是0,即永不超时。所以我们首先需要允许程序配置可超时时间:
    interface AxiosRequestConfig {
      url: string,
      method?: Method,
      headers?: any,
      data?: any,
      params?: any,
      responseType?: XMLHttpRequestResponseType,
      timeout?: number
    }
    

    src/xhr.ts

    const {/* */,  timeout} = config
    request.ontimeout = function handleTimeout() {
      reject(new Error(`Timeout of ${timeout}ms exceeded`))
    }
    
    • 处理非200状态码
    import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from "./types";
    import { parseHeaders } from "./helpers/headers";
    import { transformResponse } from "./helpers/data";
    
    export default function xhr(config: AxiosRequestConfig): AxiosPromise {
      return new Promise((resolve, reject) => {
        // method和data可能没有, 所以给出默认值
        const {
          url,
          method = 'get',
          data = null,
          headers,
          responseType,
          timeout
        } = config
        const request = new XMLHttpRequest()
        if (responseType) {
          request.responseType = responseType
        }
        if (timeout) {
          request.timeout = timeout
        }
        request.open(method.toUpperCase(), url)
        Object.keys(headers).forEach((name) => {
          request.setRequestHeader(name, headers[name])
        })
        request.onerror = function handleError() {
          reject(new Error('Network Error'))
        }
        request.onreadystatechange = function handleLoad() {
          // request.readyState不是4,说明请求还未返回
          if (request.readyState !== 4) {
            return
          }
          // 在请求未返回的时候,status为0,
          // 当XMLHttpRequest出错的时候,status也为0
          // 所以status为0的时候,不做处理
          if (request.status === 0) {
            return
          }
          const responseHeaders = request.getAllResponseHeaders()
          const responseData = responseType && responseType !== 'text' ? request.response : request.responseText
          const response: AxiosResponse = {
            data: transformResponse(responseData),
            headers: parseHeaders(responseHeaders),
            status: request.status,
            statusText: request.statusText,
            config,
            request
          }
          handleResponse(response)
        }
        request.ontimeout = function handleTimeout() {
          reject(new Error(`Timeout of ${timeout}ms exceeded`))
        }
        request.send(data)
    
        function handleResponse(response: AxiosResponse) {
          if (response.status >= 200 && response.status < 300) {
            resolve(response)
          } else {
            reject(new Error(`Request failed width status code ${response.status}`))
          }
        }
      })
    }
    
    编写demo
    import axios from '../../src/index'
    
    axios({
      method: 'get',
      url: '/api/error/get1'
    }).then((res) => {
      console.log(res)
    }).catch((e) => {
      console.log(e)
    })
    
    axios({
      method: 'get',
      url: '/api/error/get'
    }).then((res) => {
      console.log(res)
    }).catch((e) => {
      console.log(e)
    })
    
    setTimeout(() => {
      axios({
        method: 'get',
        url: '/api/error/get'
      }).then((res) => {
        console.log(res)
      }).catch((e) => {
        console.log(e)
      })
    }, 5000)
    
    axios({
      method: 'get',
      url: '/api/error/timeout',
      timeout: 2000
    }).then((res) => {
      console.log(res)
    }).catch((e) => {
      console.log(e.message)
    })
    

    至此我们对各种错误都做了处理,并且把他们都抛给了程序应用方,但是这里我们的错误都只是简单的Error实例,只有错误文本信息,并不包含是哪个请求,请求的配置,响应对象等其他信息。所以接下来我们要对报错信息进行增强。

    相关文章

      网友评论

          本文标题:3-1、处理异常情况

          本文链接:https://www.haomeiwen.com/subject/ggmdgctx.html