diff --git a/docs/zh/reference/plugin/plugins/request.md b/docs/zh/reference/plugin/plugins/request.md index b4c557f5..0978d242 100644 --- a/docs/zh/reference/plugin/plugins/request.md +++ b/docs/zh/reference/plugin/plugins/request.md @@ -65,7 +65,6 @@ export const request = { // 特殊 code 处理逻辑 }, 404(error) { - }, default(error) { // 异常统一处理 @@ -75,6 +74,32 @@ export const request = { ...otherConfigs } ``` + +#### skipErrorHandler + +- 类型: `boolean | string | number | array` +- 默认值: `` +- 详情: + + 指定当前请求的某些错误状态不走 `errorHandler`,单独进行处理。如果设置为 `true`,当前请求的错误处理都不走 `errorHandler`。 + +- 示列: + +```js +import {request} from '@fesjs/fes'; + +request('/api/login', null, { + skipErrorHandler: '110' +}).then((res) => { + // do something +}).catch((err) => { + // 这里处理 code 为 110 的异常 + // 此时 errorHandler[110] 函数不会生效,也不会执行 errorHandler.default +}) +``` + + + ## 使用 ### 发起一个普通 post 请求 diff --git a/packages/fes-plugin-request/src/template/cacheControl.js b/packages/fes-plugin-request/src/template/cacheControl.js index 03506558..fb376162 100644 --- a/packages/fes-plugin-request/src/template/cacheControl.js +++ b/packages/fes-plugin-request/src/template/cacheControl.js @@ -39,6 +39,7 @@ import { const CACHE_KEY_PREFIX = '__FES_REQUEST_CACHE:'; const CACHE_TYPE = { + merge: 'merge', // merge 重复请求 ram: 'ram', session: 'sessionStorage', local: 'localStorage' @@ -175,6 +176,11 @@ function handleCachingQueueError(ctx, config) { } } +/** + * TODO 添加一种 merge 类型 + * merge 当期所有请求,按顺序发起请求,只要有一个成功,所有请求都成功,并且跳过后续的请求。否则所有请求都失败 + * merge 错误提示 + */ export default async (ctx, next) => { const { config } = ctx; @@ -200,11 +206,14 @@ export default async (ctx, next) => { const requestdata = checkHttpRequestHasBody(config.method) ? config.data : config.params; if (!ctx.error && ctx.response && canCache(requestdata) && canCache(ctx.response.data)) { handleCachingQueueSuccess(ctx, config, ctx.response.data); - setCacheData({ - key: ctx.key, - data: ctx.response.data, - ...config.cache - }); + + if (config.cache.cacheType !== CACHE_TYPE.merge) { + setCacheData({ + key: ctx.key, + data: ctx.response.data, + ...config.cache + }); + } } else { handleCachingQueueError(ctx, config); } diff --git a/packages/fes-plugin-request/src/template/request.js b/packages/fes-plugin-request/src/template/request.js index 3655be58..66a3339c 100644 --- a/packages/fes-plugin-request/src/template/request.js +++ b/packages/fes-plugin-request/src/template/request.js @@ -65,6 +65,7 @@ function getRequestInstance() { addRequestInterceptors(instance, requestInterceptors); addResponseInterceptors(instance, responseInterceptors); + // 洋葱模型内部应该这是对数据的处理,避免有副作用调用 scheduler.use(paramsProcess) .use(genRequestKey) .use(cacheControl) @@ -120,6 +121,52 @@ function createContext(userConfig) { }; } + +function getResponseCode(response) { + if (response) { + if (response._rawData) return response._rawData.code; + if (response.data) return response.data.code; + } + return null; +} + +function skipErrorHandlerToObj(skipErrorHandler = []) { + if (!Array.isArray(skipErrorHandler)) { + skipErrorHandler = [skipErrorHandler]; + } + + return skipErrorHandler.reduce((acc, cur) => { + acc[cur] = true; + return acc; + }, {}); +} + +function handleRequestError({ + errorHandler = {}, + error, + response, + config +}) { + // 跳过所有错误类型处理 + if (config.skipErrorHandler === true) return; + + const skipObj = skipErrorHandlerToObj(config.skipErrorHandler); + const resCode = getResponseCode(response); + + let errorKey = 'default'; + if (resCode && errorHandler[resCode]) { + errorKey = resCode; + } else if (error.type && errorHandler[error.type]) { + errorKey = error.type; + } else if (error.response && errorHandler[error.response.status]) { + errorKey = error.response.status; + } + + if (!skipObj[errorKey] && errorHandler[errorKey]) { + errorHandler[errorKey](error); + } +} + export const request = (url, data, options = {}) => { if (typeof options === 'string') { options = { @@ -136,6 +183,7 @@ export const request = (url, data, options = {}) => { if (!context.error) { return context.config.useResonse ? context.response : context.response.data; } + handleRequestError(context); return Promise.reject(context.error); }); }; diff --git a/packages/fes-plugin-request/src/template/resErrorProcess.js b/packages/fes-plugin-request/src/template/resErrorProcess.js index 9d168b98..9d598b62 100644 --- a/packages/fes-plugin-request/src/template/resErrorProcess.js +++ b/packages/fes-plugin-request/src/template/resErrorProcess.js @@ -1,41 +1,16 @@ import { isObject } from './helpers'; -function handleAbnormalCode(errorHandler = {}, code, response) { - if (errorHandler[code]) { - errorHandler[code](response.data); - } else if (errorHandler.default) { - // 处理其他异常 - errorHandler.default({ - response - }); - } -} - -function handleRequestError(errorHandler = {}, error) { - if (error.type && errorHandler[error.type]) { - errorHandler[error.type](error); - } else if (error.response && errorHandler[error.response.status]) { - errorHandler[error.response.status](error); - } else if (errorHandler.default) { - errorHandler.default(error); - } -} - +// 错误处理等副作用网上提 export default async (ctx, next) => { const { - error, - errorHandler = {}, response, config } = ctx; if (!config.closeResDataCheck && response && isObject(response.data)) { const code = response.data.code; if (code !== '0') { - handleAbnormalCode(errorHandler, code, response); ctx.error = response; // code 不为零进入 reject } - } else if (error) { - handleRequestError(errorHandler, error); } await next(); diff --git a/packages/fes-template-h5/src/app.js b/packages/fes-template-h5/src/app.js index dd9fb08c..9da182a1 100644 --- a/packages/fes-template-h5/src/app.js +++ b/packages/fes-template-h5/src/app.js @@ -1,7 +1,7 @@ export const request = { errorHandler: { - 111(responseData) { - console.log(responseData); + 111() { + console.log('root:111'); }, 500() { console.log('500 error'); diff --git a/packages/fes-template-h5/src/pages/index.vue b/packages/fes-template-h5/src/pages/index.vue index 13d5800b..39daf7cd 100644 --- a/packages/fes-template-h5/src/pages/index.vue +++ b/packages/fes-template-h5/src/pages/index.vue @@ -12,18 +12,13 @@ }