美文网首页
四、错误处理-需求分析-网络错误+非200状态码

四、错误处理-需求分析-网络错误+非200状态码

作者: 雪燃归来 | 来源:发表于2020-04-21 23:21 被阅读0次

在前一章节,我们实现了ts-axios的Promise封装和构建,完成了请求发送成功和成功获取数据后的处理操作。本篇我们将完成ts-axios面对各种错误时的处理方式。这些错误包括网络延时请求未找到(非200状态)服务器返回错误(500状态)等。

一、修改xhr对象

文件位置: /src/xhr.ts
此处为了代码的完整性,我把整个代码片段都贴了出来。整体代码都比较直观,注释也比较详细。

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

export default function xhr(config: AxiosRequestConfig): AxiosPromise {
  return new Promise((resolve, reject) => {
    const { data, url, method = 'get', headers, responseType, timeout } = config
    // 创建XHR请求对象的实例
    const request = new XMLHttpRequest()
    /**如果存在responseType */
    if (responseType) {
      request.responseType = responseType
    }
    /**设置请求时间 */
    if (timeout) {
      request.timeout = timeout
    }
    /**发送请求 */
    request.open(method.toUpperCase(), url, true)
    /**处理相应后的数据 */
    request.onreadystatechange = function handleLoad() {
      if (request.readyState !== 4) {
        return
      }
      if (request.status === 0) {
        return
      }
      const responseHeaders = parseHeaders(request.getAllResponseHeaders())
      const responseData = responseType !== 'text' ? request.response : request.responseText
      const response: AxiosResponse = {
        data: responseData,
        status: request.status,
        statusText: request.statusText,
        headers: responseHeaders,
        config,
        request
      }
      handleResponse(response)
    }
    /**网络错误处理 */
    request.onerror = function() {
      reject(new Error('Network Error!'))
    }
    /**处理请求错误 */
    request.ontimeout = function() {
      reject(new Error(`Timeout of ${timeout} ms exceeded`))
    }
    /**处理网络请求头 */
    Object.keys(headers).forEach(name => {
      if (data === null && name.toLowerCase() === 'content-type') {
        delete headers[name]
      } else {
        request.setRequestHeader(name, headers[name])
      }
    })
    request.send(data)

    // 处理状态码函数
    function handleResponse(response: AxiosResponse): void {
      if (response.status >= 200 && response.status < 300) {
        resolve(response)
      } else {
        reject(`Request failed with status code ${response.status}`)
      }
    }
  })
}

二、修改AxiosResponse接口类型,新增timeout属性

文件位置: /src/types/index.ts

export interface AxiosRequestConfig {
  url: string
  method?: Method
  data?: any
  params?: any
  headers?: any
  responseType?: XMLHttpRequestResponseType
  timeout?: number
}

三、编写测试用例

import axios from '../../src/index'

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

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

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

在编写用例的时候,第三个测试用例需要我们注意一下。因为它没设置了5000ms后调用,这个用例是为了测试延迟函数调用的,所以我们应该遵循下面的操作流程。
在请求刚开始的时候,将浏览器network面板中网络设置为online,然后这只为offline(5秒内),这样就可以测试超时调用了。

四、优化错误处理

通过上面的步骤,我们实现了对ts-axios错误的相关的处理,但是对于这样的处理来说,显得有些简单,因为我们只是简单的返回一段错误的提示,我们还应该将错误的编号、请求的配置等信息返回,方便我们快速定位错误。

1、新增错误类型

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

2、创建error处理函数

文件位置 /src/helper/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
): AxiosError {
  const error = new AxiosError(message, config, code, request, response)
  return error
}

3、重构错误返回值

import { createError } from '../helpers/error'
...
/**网络错误处理 */
request.onerror = function() {
   reject(createError('Network Error!', config, null, request))
}
/**处理请求错误 */
request.ontimeout = function() {
   reject(createError(`Timeout of ${timeout} ms exceeded`, config, null, request))
}

通过上面对错误处理的优化,我们可以返回更加确切的错误提示了,我们可以以下面的测试用例来检测一下我们优化的成果。

axios({
  method: 'get',
  url: '/error/timeout',
  timeout: 2000
})
  .then(res => {
    console.log(res)
  })
  .catch((e: AxiosError) => {
    console.log(e.message)
    console.log(e.config)
    console.log(e.code)
    console.log(e.request)
    console.log(e.isAxiosError)
  })

相关文章

  • 四、错误处理-需求分析-网络错误+非200状态码

    在前一章节,我们实现了ts-axios的Promise封装和构建,完成了请求发送成功和成功获取数据后的处理操作。本...

  • 错误码规范

    区别业务错误和http status状态错误 默认情况下,http非200错误码都属于网络或者接入层的错误,都正常...

  • axios的封装使用

    axios是经常使用到的网络请求库,因此我们需要简单的封装一下。主要的作用就是统一http状态码处理,统一错误处理...

  • 状态码

    100-199 信息性状态码 200-299 成功状态码 (常见200表示请求成功) 400-499 客户端错误状...

  • 服务端与网络题目

    服务端与网络 1、常见状态码 2、缓存 200 From cache和200 ok400,401,403状态码分别...

  • HTTP协议

    状态码 200 服务器已成功处理了请求 状态码 400 客户端的请求语法错误 服务器无法解析 状态码 40...

  • 接口测试返回码状态含义

    http网络请求 返回statusCode(状态码) 200、300、400、500。。。 4XXHTTP状态码表...

  • 第四章第8节 LR分析中的错误处理

    LR分析中的错误处理 恐慌模式错误恢复 短语层次错误恢复

  • 网络请求错误状态码

    https://en.wikipedia.org/wiki/List_of_HTTP_status_codes摘抄...

  • HTTP常见状态码

    HTTP常见状态码(404、400、500)等错误 一些常见的状态码为: 200 - 服务器成功返回网页404 -...

网友评论

      本文标题:四、错误处理-需求分析-网络错误+非200状态码

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