RequestHandler.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import ApiConfig from "./RequestApiConfig";
  2. import { DataModel, type NewDataModel } from "@imengyu/js-request-transform";
  3. import { RequestApiError, type RequestApiErrorType, RequestApiResult } from "./RequestApiResult";
  4. import { RequestCoreInstance, RequestOptions, Response } from "./RequestCore";
  5. /**
  6. * 请求错误与数据处理函数
  7. *
  8. * 这里写的是请求中的 数据处理函数 与 错误默认处理函数。
  9. *
  10. * 业务相关的自定义数据处理函数,请单独在RequestModules中写明。
  11. *
  12. * Author: imengyu
  13. * Date: 2022/03/28
  14. *
  15. * Copyright (c) 2021 imengyu.top. Licensed under the MIT License.
  16. * See License.txt in the project root for license information.
  17. */
  18. //默认的请求数据处理函数
  19. export function defaultResponseDataHandler<T extends DataModel>(response: Response, req: RequestOptions, resultModelClass: NewDataModel|undefined, instance: RequestCoreInstance<T>, apiName: string|undefined) : Promise<RequestApiResult<T>> {
  20. return new Promise<RequestApiResult<T>>((resolve, reject) => {
  21. const method = req.method || 'GET';
  22. response.json().then((json) => {
  23. //情况1,有返回数据
  24. if (response.ok) {
  25. if (ApiConfig.getConfig().EnableApiRequestLog)
  26. console.log(`[API Debugger] Request [${method}] ` + response.url + ' success (' + response.status + ') ' + (ApiConfig.getConfig().EnableApiDataLog ? JSON.stringify(json) : ''));
  27. //情况1-1,请求成功,状态码200-299
  28. resolve(new RequestApiResult(resultModelClass ?? instance.config.modelClassCreator, response.status, json.message, json.data, json));
  29. } else {
  30. if (ApiConfig.getConfig().EnableApiRequestLog)
  31. console.log(`[API Debugger] Request [${method}] ${response.url} Got error from server : ` + json.message + ' (' + json.code + ') ' + (ApiConfig.getConfig().EnableApiDataLog ? JSON.stringify(json) : ''));
  32. //情况1-2,请求失败,状态码>299
  33. const err = new RequestApiError('statusError', json.message, '状态码异常', json.code || response.status, json.data, json, req, apiName, response.url);
  34. //错误报告
  35. if (instance.checkShouldReportError(err))
  36. instance.reportError(err);
  37. reject(err);
  38. }
  39. }).catch((err) => {
  40. //错误统一处理
  41. defaultResponseDataHandlerCatch(method, req, response, null, err, apiName, response.url, reject, instance);
  42. });
  43. });
  44. }
  45. export function defaultResponseDataGetErrorInfo(response: Response, err: any) {
  46. let errString = (response.status > 299) ? ('返回了状态码' + response.status + '。\n') : '';
  47. let errType : RequestApiErrorType = 'statusError';
  48. let errCodeStr = '状态码:' + response.status;
  49. if (err instanceof Error && response.status < 299) {
  50. errString = '代码错误: ' + err.message;
  51. errType = 'scriptError';
  52. } else {
  53. if (('' + err).indexOf('JSON Parse error') >= 0)
  54. errString += '处理JSON结构失败,可能后端没有返回正确的JSON格式。\n';
  55. //情况2,没有返回数据
  56. //错误状态码的处理
  57. switch (response.status) {
  58. case 400:
  59. errCodeStr = '错误的请求';
  60. errString += errCodeStr + ' \n[提示:请检查传入参数是否正确]';
  61. errType = 'statusError';
  62. break;
  63. case 401:
  64. errCodeStr = '未登录。可能登录已经过期,请重新登录';
  65. errString += errCodeStr;
  66. errType = 'statusError';
  67. break;
  68. case 405:
  69. errCodeStr = 'HTTP方法不被允许';
  70. errString += errCodeStr + ' \n[提示:这可能是调用接口是不正确造成的]';
  71. errType = 'statusError';
  72. break;
  73. case 404:
  74. errCodeStr = '返回404未找到';
  75. errString += errCodeStr + ' \n[提示:后端检查下到底有没有提供这个API?]';
  76. errType = 'statusError';
  77. break;
  78. case 500:
  79. errCodeStr = '服务异常,请稍后重试';
  80. errString += errCodeStr + ' \n[故障提示:这可能是后端服务出现了异常]';
  81. errType = 'serverError';
  82. break;
  83. case 502:
  84. errCodeStr = '无效网关,请反馈此错误';
  85. errString += errCodeStr + ' \n[故障提示:请检查服务器与软件状态]';
  86. errType = 'serverError';
  87. break;
  88. case 503:
  89. errCodeStr = '服务暂时不可用';
  90. errString += errCodeStr + ' \n[故障提示:请检查服务器状态]';
  91. errType = 'serverError';
  92. break;
  93. }
  94. }
  95. return {errString, errType, errCodeStr};
  96. }
  97. //默认的请求数据处理函数
  98. export function defaultResponseDataHandlerCatch<T extends DataModel>(method: string, req: RequestOptions, response: Response, data: any, err: any, apiName: string|undefined, apiUrl: string, reject: (reason?: any) => void, instance: RequestCoreInstance<T>) {
  99. if (ApiConfig.getConfig().EnableApiRequestLog) {
  100. console.log(`[API Debugger] E > ${apiName} ` + err + ' status: ' + response.status);
  101. if (err instanceof Error)
  102. console.log(err.stack);
  103. }
  104. const {errString, errType, errCodeStr} = defaultResponseDataGetErrorInfo(response, err);
  105. const errObj = new RequestApiError(errType, errString, errCodeStr, response.status, null, data, req, apiName, apiUrl);
  106. //错误报告
  107. if (instance.checkShouldReportError(errObj))
  108. instance.reportError(errObj);
  109. reject(errObj);
  110. }
  111. //默认的请求错误处理函数
  112. export function defaultResponseErrorHandler(err: Error) : RequestApiError {
  113. if (err instanceof Error)
  114. console.error('[API Debugger] Error : ' + err + (err.stack ? ('\n' + err.stack) : ''));
  115. else
  116. console.error('[API Debugger] Error : ' + JSON.stringify(err));
  117. return new RequestApiError('unknow', '' + JSON.stringify(err));
  118. }