refactor(aixos): 完善axios错误处理流程

This commit is contained in:
chen.home 2023-01-12 00:25:48 +08:00
parent 204cb7ad9f
commit ef6392615b
5 changed files with 442 additions and 323 deletions

View File

@ -10,13 +10,13 @@ import {
} from '@/config';
type ErrorStatus = keyof typeof ERROR_STATUS;
/**
* @description: axios返回的http错误
* @description: axioshttp错误
* @param {AxiosError} err
* @return {*}
*/
export function handleHttpError(err: AxiosError) {
export function handleAxiosError(err: AxiosError) {
const error = {
type: 'axios',
type: 'Axios',
code: DEFAULT_REQUEST_ERROR_CODE,
msg: DEFAULT_REQUEST_ERROR_MSG,
};
@ -43,9 +43,42 @@ export function handleHttpError(err: AxiosError) {
/**
* @description: axios请求成功
* @param {AxiosResponse} err
* @param {AxiosResponse} response
* @return {*}
*/
// export function handleResponseError(err: AxiosResponse) {}
export function handleResponseError(response: AxiosResponse) {
const error = {
type: 'Axios',
code: DEFAULT_REQUEST_ERROR_CODE,
msg: DEFAULT_REQUEST_ERROR_MSG,
};
// export function handleBusinessError() {}
if (!window.navigator.onLine) {
// 网路错误
Object.assign(error, { code: NETWORK_ERROR_CODE, msg: NETWORK_ERROR_MSG });
} else {
// 请求成功的状态码非200的错误
const errorCode: ErrorStatus = response.status as ErrorStatus;
const msg = ERROR_STATUS[errorCode] || DEFAULT_REQUEST_ERROR_MSG;
Object.assign(error, { type: 'Response', code: errorCode, msg });
}
return error;
}
/**
* @description:
* @param {Record} apiData
* @param {Service} config axios字段配置
* @return {*}
*/
export function handleBusinessError(apiData: Record<string, any>, config: Service.BackendResultConfig) {
const { codeKey, msgKey } = config;
const error = {
type: 'Business',
code: apiData[codeKey],
msg: apiData[msgKey],
};
return error;
}

View File

@ -1,8 +1,7 @@
import axios from 'axios';
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import { getToken } from '@/utils';
// import { handleHttpError, handleResponseError, handleBusinessError } from './help';
import { handleHttpError } from './help';
import { handleAxiosError, handleResponseError, handleBusinessError } from './handle';
/**
* @description: axios请求类
@ -34,34 +33,44 @@ export default class createAxiosInstance {
// 设置类拦截器的函数
setInterceptor() {
this.instance.interceptors.request.use(
(config: AxiosRequestConfig) => {
// 一般会请求拦截里面加token
config.headers!.Authorization = getToken();
return config;
async (config) => {
const handleConfig = { ...config };
if (handleConfig.headers) {
// 设置token
typeof handleConfig.headers.set === 'function' &&
handleConfig.headers.set('Authorization', `Bearer ${getToken() || ''}`);
}
return handleConfig;
},
(err: any) => Promise.reject(err)
(axiosError: AxiosError) => {
const error = handleAxiosError(axiosError);
Promise.reject(error);
}
);
this.instance.interceptors.response.use(
// 因为接口的数据都在res.data下所以直接返回res.data
// 系统如果有自定义code也可以在这里处理
(res: AxiosResponse) => {
// apiData 是 API 返回的数据
const apiData = res.data;
// 这个 Code 是和后端约定的业务 Code
const code = String(res.data[this.backendConfig.codeKey]);
switch (code) {
case this.backendConfig.successCode:
// code === 200 代表没有错误,直接返回约定的数据内容
async (response) => {
const { status } = response;
if (status === 200) {
// 获取返回的数据
const apiData = response.data;
const { codeKey, successCode } = this.backendConfig;
// 请求成功
if (apiData[codeKey] == successCode) {
// return apiData[dataKey];
return apiData;
default:
// 不是正确的 Code,返回错误提示信息
return Promise.reject(new Error(`Error:${this.backendConfig.dataKey}`));
}
//TODO 添加刷新token的操作
// 业务请求失败
const error = handleBusinessError(apiData, this.backendConfig);
return Promise.reject(error);
}
// 接口请求失败
const error = handleResponseError(response);
return Promise.reject(error);
},
(err: AxiosError) => {
// 这里用来处理http常见错误进行全局提示等
const error = handleHttpError(err);
// 这里是AxiosError类型所以一般我们只reject我们需要的响应即可
(axiosError: AxiosError) => {
// 处理http常见错误进行全局提示等
const error = handleAxiosError(axiosError);
return Promise.reject(error);
}
);

View File

@ -80,11 +80,11 @@ export const useRouteStore = defineStore('route-store', {
async initDynamicRoute() {
// 根据用户id来获取用户的路由
const { userId } = getUserInfo();
const { data } = await fetchUserRoutes(userId);
const { data: routes } = await fetchUserRoutes(userId);
// 根据用户返回的路由表来生成真实路由
const appRoutes = await createDynamicRoutes(data);
const appRoutes = await createDynamicRoutes(routes);
// 生成侧边菜单
await this.createMenus(data);
await this.createMenus(routes);
// 插入路由表
router.addRoute(appRoutes);
},

View File

@ -1,29 +1,76 @@
<template>
<n-space vertical size="large">
<n-space
vertical
size="large"
>
<n-card>
<n-form ref="formRef" :model="model" label-placement="left" :show-feedback="false">
<n-grid :x-gap="30" :cols="18">
<n-form-item-gi :span="4" label="姓名" path="condition_1">
<n-input v-model:value="model.condition_1" placeholder="请输入" />
<n-form
ref="formRef"
:model="model"
label-placement="left"
:show-feedback="false"
>
<n-grid
:x-gap="30"
:cols="18"
>
<n-form-item-gi
:span="4"
label="姓名"
path="condition_1"
>
<n-input
v-model:value="model.condition_1"
placeholder="请输入"
/>
</n-form-item-gi>
<n-form-item-gi :span="4" label="年龄" path="condition_2">
<n-input v-model:value="model.condition_2" placeholder="请输入" />
<n-form-item-gi
:span="4"
label="年龄"
path="condition_2"
>
<n-input
v-model:value="model.condition_2"
placeholder="请输入"
/>
</n-form-item-gi>
<n-form-item-gi :span="4" label="性别" path="condition_3">
<n-input v-model:value="model.condition_3" placeholder="请输入" />
<n-form-item-gi
:span="4"
label="性别"
path="condition_3"
>
<n-input
v-model:value="model.condition_3"
placeholder="请输入"
/>
</n-form-item-gi>
<n-form-item-gi :span="4" label="地址" path="condition_4">
<n-input v-model:value="model.condition_4" placeholder="请输入" />
<n-form-item-gi
:span="4"
label="地址"
path="condition_4"
>
<n-input
v-model:value="model.condition_4"
placeholder="请输入"
/>
</n-form-item-gi>
<n-gi :span="1">
<n-button type="primary">
<template #icon><i-icon-park-outline-search /></template>
<template #icon>
<i-icon-park-outline-search />
</template>
搜索
</n-button>
</n-gi>
<n-gi :span="1">
<n-button strong secondary @click="handleResetSearch">
<template #icon><i-icon-park-outline-redo /></template>
<n-button
strong
secondary
@click="handleResetSearch"
>
<template #icon>
<i-icon-park-outline-redo />
</template>
重置
</n-button>
</n-gi>
@ -31,24 +78,54 @@
</n-form>
</n-card>
<n-card>
<n-space vertical size="large">
<n-space
vertical
size="large"
>
<div class="flex gap-4">
<n-button type="primary" @click="handleAddTable">
<template #icon><i-icon-park-outline-add-one /></template>
<n-button
type="primary"
@click="handleAddTable"
>
<template #icon>
<i-icon-park-outline-add-one />
</template>
新建
</n-button>
<n-button strong secondary>
<template #icon><i-icon-park-outline-afferent /></template>
<n-button
strong
secondary
>
<template #icon>
<i-icon-park-outline-afferent />
</template>
批量导入
</n-button>
<n-button strong secondary class="ml-a">
<template #icon><i-icon-park-outline-download /></template>
<n-button
strong
secondary
class="ml-a"
>
<template #icon>
<i-icon-park-outline-download />
</template>
下载
</n-button>
</div>
<n-data-table :columns="columns" :data="listData" :loading="loading" />
<Pagination :count="100" @change="changePage" />
<TableModal v-model:visible="visible" :type="modalType" :modal-data="editData" />
<n-data-table
:columns="columns"
:data="listData"
:loading="loading"
/>
<Pagination
:count="100"
@change="changePage"
/>
<TableModal
v-model:visible="visible"
:type="modalType"
:modal-data="editData"
/>
</n-space>
</n-card>
</n-space>