errorHandler.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /**
  2. * 错误处理工具类
  3. */
  4. // 错误码映射表
  5. const ERROR_CODE_MAP = {
  6. 400: '请求参数错误',
  7. 401: '登录已过期,请重新登录',
  8. 403: '没有权限执行此操作',
  9. 404: '请求的资源不存在',
  10. 500: '服务器错误,请稍后重试',
  11. 502: '网关错误',
  12. 503: '服务不可用,请稍后重试',
  13. 504: '网关超时'
  14. };
  15. // 业务错误码映射表(根据实际业务定义)
  16. const BUSINESS_ERROR_CODE_MAP = {
  17. 10001: '用户名或密码错误',
  18. 10002: '账号已被禁用',
  19. 10003: '验证码错误',
  20. 10004: '操作过于频繁,请稍后再试',
  21. // 添加更多业务错误码...
  22. };
  23. class ErrorHandler {
  24. constructor() {
  25. // 记录最后显示的错误信息和时间,避免重复显示
  26. this.lastMessage = '';
  27. this.lastTime = 0;
  28. }
  29. /**
  30. * 显示错误提示
  31. * @param {string} message - 错误信息
  32. * @param {number} duration - 显示时长
  33. */
  34. showError(message, duration = 2000) {
  35. // 避免重复显示相同的错误提示
  36. if (this.lastMessage === message && Date.now() - this.lastTime < 3000) {
  37. return;
  38. }
  39. uni.showToast({
  40. title: message,
  41. icon: 'none',
  42. duration: duration
  43. });
  44. // 记录最后显示的错误信息和时间
  45. this.lastMessage = message;
  46. this.lastTime = Date.now();
  47. }
  48. /**
  49. * 处理HTTP错误
  50. * @param {number} statusCode - HTTP状态码
  51. * @param {Object} response - 响应对象
  52. * @returns {Error} - 格式化的错误对象
  53. */
  54. handleHttpError(statusCode, response) {
  55. const errorMsg = ERROR_CODE_MAP[statusCode] || `网络请求错误:${statusCode}`;
  56. this.showError(errorMsg);
  57. const error = new Error(errorMsg);
  58. error.code = statusCode;
  59. error.response = response;
  60. // 特殊处理401未授权错误
  61. if (statusCode === 401) {
  62. this.handleUnauthorized();
  63. }
  64. return error;
  65. }
  66. /**
  67. * 处理业务错误
  68. * @param {Object} data - 业务响应数据
  69. * @returns {Error} - 格式化的错误对象
  70. */
  71. handleBusinessError(data) {
  72. const errorMsg = BUSINESS_ERROR_CODE_MAP[data.code] || data.msg || '请求失败';
  73. this.showError(errorMsg);
  74. const error = new Error(errorMsg);
  75. error.code = data.code;
  76. error.data = data;
  77. return error;
  78. }
  79. /**
  80. * 处理网络请求失败
  81. * @param {Object} err - 原始错误对象
  82. * @returns {Error} - 格式化的错误对象
  83. */
  84. handleRequestFail(err) {
  85. let errorMsg = '网络请求失败,请检查网络连接';
  86. // 根据错误类型提供更具体的错误信息
  87. if (err.errMsg) {
  88. if (err.errMsg.includes('timeout')) {
  89. errorMsg = '请求超时,请检查网络连接';
  90. } else if (err.errMsg.includes('abort')) {
  91. errorMsg = '请求已取消';
  92. } else if (err.errMsg.includes('SSL')) {
  93. errorMsg = '网络安全证书错误';
  94. }
  95. }
  96. this.showError(errorMsg);
  97. const error = new Error(errorMsg);
  98. error.original = err;
  99. return error;
  100. }
  101. /**
  102. * 处理未授权错误(401)
  103. */
  104. handleUnauthorized() {
  105. // 清除登录信息
  106. uni.removeStorageSync('token');
  107. uni.removeStorageSync('userInfo');
  108. // 跳转到登录页
  109. setTimeout(() => {
  110. uni.navigateTo({
  111. url: '/pages/login/login'
  112. });
  113. }, 1500);
  114. }
  115. /**
  116. * 记录错误日志
  117. * @param {Error} error - 错误对象
  118. * @param {string} source - 错误来源
  119. */
  120. logError(error, source = 'unknown') {
  121. console.error(`[${source}] Error:`, error);
  122. // 这里可以添加错误上报逻辑
  123. // 例如发送到服务器或第三方监控平台
  124. }
  125. }
  126. // 创建单例
  127. const errorHandler = new ErrorHandler();
  128. export default errorHandler;