/** * 统一错误处理工具 * 提供统一的错误提示和处理机制 */ /** * 错误类型映射 */ const ERROR_TYPES = { NETWORK: 'network', AUTH: 'auth', BUSINESS: 'business', UNKNOWN: 'unknown' } /** * 错误消息映射 */ const ERROR_MESSAGES = { // 网络错误 'request:fail': '网络连接失败,请检查网络设置', 'request:fail timeout': '请求超时,请稍后重试', 'request:fail abort': '请求已取消', // 认证错误 401: '登录已过期,请重新登录', 403: '没有权限访问', // 业务错误 400: '请求参数错误', 404: '请求的资源不存在', 500: '服务器错误,请稍后重试', // 默认错误 default: '操作失败,请稍后重试' } /** * 判断错误类型 * @param {object} error - 错误对象 * @returns {string} 错误类型 */ function getErrorType(error) { if (!error) return ERROR_TYPES.UNKNOWN // 网络错误 if (error.errMsg && error.errMsg.includes('request:fail')) { return ERROR_TYPES.NETWORK } // 认证错误 if (error.code === 401 || error.statusCode === 401) { return ERROR_TYPES.AUTH } // 业务错误 if (error.code || error.statusCode) { return ERROR_TYPES.BUSINESS } return ERROR_TYPES.UNKNOWN } /** * 获取错误消息 * @param {object} error - 错误对象 * @returns {string} 错误消息 */ function getErrorMessage(error) { if (!error) return ERROR_MESSAGES.default // 优先使用后端返回的错误消息 if (error.message) return error.message if (error.error) return error.error if (error.msg) return error.msg // 根据错误码获取消息 const code = error.code || error.statusCode if (code && ERROR_MESSAGES[code]) { return ERROR_MESSAGES[code] } // 根据错误信息获取消息 if (error.errMsg && ERROR_MESSAGES[error.errMsg]) { return ERROR_MESSAGES[error.errMsg] } return ERROR_MESSAGES.default } /** * 显示错误提示 * @param {object} error - 错误对象 * @param {object} options - 选项 */ function showError(error, options = {}) { const { silent = false, // 是否静默(不显示提示) duration = 2000, // 提示持续时间 icon = 'none', // 图标类型 mask = false // 是否显示透明蒙层 } = options if (silent) return const message = getErrorMessage(error) const type = getErrorType(error) // 认证错误不显示toast,由auth模块处理 if (type === ERROR_TYPES.AUTH) { return } wx.showToast({ title: message, icon, duration, mask }) } /** * 处理API错误 * @param {object} error - 错误对象 * @param {object} options - 选项 * @returns {object} 处理后的错误对象 */ function handleApiError(error, options = {}) { const { showToast = true, // 是否显示错误提示 logError = true, // 是否记录错误日志 customMessage = null // 自定义错误消息 } = options // 记录错误日志 if (logError) { console.error('[Error Handler]', error) } // 显示错误提示 if (showToast) { showError(error, { silent: false, duration: 2000 }) } // 返回标准化的错误对象 return { type: getErrorType(error), message: customMessage || getErrorMessage(error), code: error.code || error.statusCode || -1, originalError: error } } /** * 错误重试机制 * @param {function} fn - 要重试的函数 * @param {object} options - 选项 * @returns {Promise} */ async function retryOnError(fn, options = {}) { const { maxRetries = 3, // 最大重试次数 retryDelay = 1000, // 重试延迟(毫秒) onRetry = null // 重试回调 } = options let lastError = null for (let i = 0; i < maxRetries; i++) { try { return await fn() } catch (error) { lastError = error // 认证错误不重试 if (getErrorType(error) === ERROR_TYPES.AUTH) { throw error } // 最后一次重试失败,抛出错误 if (i === maxRetries - 1) { throw error } // 执行重试回调 if (onRetry) { onRetry(i + 1, maxRetries) } // 等待后重试 await new Promise(resolve => setTimeout(resolve, retryDelay)) } } throw lastError } /** * 检查网络状态 * @returns {Promise} */ function checkNetworkStatus() { return new Promise((resolve) => { wx.getNetworkType({ success: (res) => { const networkType = res.networkType if (networkType === 'none') { wx.showToast({ title: '网络未连接', icon: 'none', duration: 2000 }) resolve(false) } else { resolve(true) } }, fail: () => { resolve(true) // 获取失败时假设网络正常 } }) }) } module.exports = { ERROR_TYPES, ERROR_MESSAGES, getErrorType, getErrorMessage, showError, handleApiError, retryOnError, checkNetworkStatus }