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

View File

@ -80,11 +80,11 @@ export const useRouteStore = defineStore('route-store', {
async initDynamicRoute() { async initDynamicRoute() {
// 根据用户id来获取用户的路由 // 根据用户id来获取用户的路由
const { userId } = getUserInfo(); 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); router.addRoute(appRoutes);
}, },

View File

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