errorHandler.js 3.7 KB

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