知识管理文档 知识管理文档
首页
  • 学习笔记

    • 记录
  • 学习教程

    • ES6
    • Vue
    • Git
  • Java全栈

    • java进阶
    • SpringBoot
  • Golang

    • GoWeb
  • Python

    • Django
  • 总结
  • Docker
  • Linux
  • Mysql
  • Redis
  • Nginx
  • 区块链
  • 后端开发
  • FISCOBCOS

    • JavaSDK快速开发
  • Fabric

    • 链码的使用
  • XuperChain

    • 测试
技术文档
Ocean
GitHub (opens new window)
首页
  • 学习笔记

    • 记录
  • 学习教程

    • ES6
    • Vue
    • Git
  • Java全栈

    • java进阶
    • SpringBoot
  • Golang

    • GoWeb
  • Python

    • Django
  • 总结
  • Docker
  • Linux
  • Mysql
  • Redis
  • Nginx
  • 区块链
  • 后端开发
  • FISCOBCOS

    • JavaSDK快速开发
  • Fabric

    • 链码的使用
  • XuperChain

    • 测试
技术文档
Ocean
GitHub (opens new window)
  • 初识 TypeScript

    • 简介
    • 安装 TypeScript
    • 编写第一个 TypeScript 程序
  • TypeScript 常用语法

    • 基础类型
    • 变量声明
    • 接口
    • 类
    • 函数
    • 泛型
    • 类型推断
    • 高级类型
  • ts-axios 项目初始化

    • 需求分析
    • 初始化项目
    • 编写基础请求代码
  • ts-axios 基础功能实现

    • 处理请求 url 参数
    • 处理请求 body 数据
    • 处理请求 header
    • 获取响应数据
    • 处理响应 header
    • 处理响应 data
  • ts-axios 异常情况处理

    • 错误处理
    • 错误信息增强
      • 需求分析
      • 创建 AxiosError 类
      • createError 方法应用
      • 导出类型定义
  • ts-axios 接口扩展

    • 扩展接口
    • axios 函数重载
    • 响应数据支持泛型
  • ts-axios 拦截器实现

    • 拦截器设计与实现
  • ts-axios 配置化实现

    • 合并配置的设计与实现
    • 请求和响应配置化
    • 扩展 create 静态接口
  • ts-axios 取消功能实现

    • 取消功能的设计与实现
  • ts-axios 更多功能实现

    • withCredentials
    • XSRF 防御
    • 上传和下载的进度监控
    • HTTP 授权
    • 自定义合法状态码
    • 自定义参数序列化
    • baseURL
    • 静态方法扩展
  • ts-axios 单元测试

    • 前言
    • Jest 安装和配置
    • 辅助模块单元测试
    • 请求模块单元测试
    • headers 模块单元测试
    • Axios 实例模块单元测试
    • 拦截器模块单元测试
    • mergeConfig 模块单元测试
    • 请求取消模块单元测试
    • 剩余模块单元测试
  • ts-axios 部署与发布

    • ts-axios 编译与发布
    • 引用 ts-axios 库
  • 《TypeScript 从零实现 axios》
  • ts-axios 异常情况处理
HuangYi
2020-01-05
目录

错误信息增强

# 错误信息增强

# 需求分析

上一节课我们已经捕获了几类 AJAX 的错误,但是对于错误信息提供的非常有限,我们希望对外提供的信息不仅仅包含错误文本信息,还包括了请求对象配置 config,错误代码 code,XMLHttpRequest 对象实例 request以及自定义响应对象 response。

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)
})

这样对于应用方来说,他们就可以捕获到这些错误的详细信息,做进一步的处理。

那么接下来,我们就来对错误信息做增强。

# 创建 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

    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
}

AxiosError 继承于 Error 类,添加了一些自己的属性:config、code、request、response、isAxiosError 等属性。这里要注意一点,我们使用了 Object.setPrototypeOf(this, AxiosError.prototype),这段代码的目的是为了解决 TypeScript 继承一些内置对象的时候的坑,参考 (opens new window)。

另外,为了方便使用,我们对外暴露了一个 createError 的工厂方法。

# createError 方法应用

修改关于错误对象创建部分的逻辑,如下:

xhr.ts:

import { createError } from './helpers/error'

request.onerror = function handleError() {
  reject(createError(
    'Network Error',
    config,
    null,
    request
  ))
}

request.ontimeout = function handleTimeout() {
  reject(createError(
    `Timeout of ${config.timeout} ms exceeded`,
    config,
    'ECONNABORTED',
    request
  ))
}

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

# 导出类型定义

在 demo 中,TypeScript 并不能把 e 参数推断为 AxiosError 类型,于是我们需要手动指明类型,为了让外部应用能引入 AxiosError 类型,我们也需要把它们导出。

我们创建 axios.ts 文件,把之前的 index.ts 的代码拷贝过去,然后修改 index.ts 的代码。

index.ts:

import axios from './axios'

export * from './types'

export default axios

这样我们在 demo 中就可以引入 AxiosError 类型了。

examples/error/app.ts:

import axios, { AxiosError } from '../../src/index'

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

至此,我们关于 ts-axios 的异常处理逻辑就告一段落。下面的章节,我们会对 ts-axios 的接口做扩展,让它提供更多好用和方便的 API。

错误处理
扩展接口

← 错误处理 扩展接口→

Theme by Vdoing | Copyright © 2023-2024 Deep Sea | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式