UNPKG

openchain-sdk-yxl-wx-request

Version:

openchain sd YxL wx request

321 lines (280 loc) 8.6 kB
# 错误处理 OpenChain SDK 提供了标准化的错误处理机制,包括错误码、错误描述以及处理建议。 ## 错误处理基础 ### 基本错误处理结构 ```javascript try { const response = yield sdk.account.getInfo(address); if (response.errorCode !== 0) { console.error('错误码:', response.errorCode); console.error('错误描述:', response.errorDesc); throw new Error(`操作失败: [${response.errorCode}] ${response.errorDesc}`); } return response.result; } catch (error) { console.error('异常:', error.message); throw error; } ``` ### 标准响应格式 ```javascript // 成功响应 { errorCode: 0, errorDesc: '', result: { // 操作结果 } } // 错误响应 { errorCode: 11002, errorDesc: '无效的源地址', result: null } ``` ## 错误码分类 ### 账户相关错误 (11001-11006) ```javascript const AccountErrors = { CREATE_ACCOUNT_ERROR: 11001, // 创建账户失败 INVALID_SOURCE_ADDRESS: 11002, // 无效的源地址 INVALID_DEST_ADDRESS: 11003, // 无效的目标地址 INVALID_INIT_BALANCE: 11004, // 初始余额必须在1和int64最大值之间 SAME_SOURCE_DEST: 11005, // 源地址不能等于目标地址 INVALID_ADDRESS: 11006 // 无效的地址格式 }; ``` ### 资产相关错误 (11008, 11023-11024) ```javascript const AssetErrors = { INVALID_ISSUE_AMOUNT: 11008, // 发行金额必须在1和int64最大值之间 INVALID_ASSET_CODE: 11023, // 无效的资产代码 INVALID_AMOUNT: 11024 // 资产金额必须在1和int64最大值之间 }; ``` ### Token相关错误 (11030-11043) ```javascript const TokenErrors = { TOKEN_NOT_EXIST: 11030, // Token不存在 INVALID_TOKEN_NAME: 11031, // Token名称长度必须在1到1024之间 INVALID_TOKEN_SYMBOL: 11032, // Token符号长度必须在1到1024之间 INVALID_TOKEN_DECIMALS: 11033, // Token精度必须在0到8之间 INVALID_TOKEN_SUPPLY: 11034, // Token总供应量必须在1和int64最大值之间 INVALID_TOKEN_OWNER: 11035 // 无效的Token所有者 }; ``` ### 合约相关错误 (11044-11047) ```javascript const ContractErrors = { EMPTY_PAYLOAD: 11044, // 载荷不能为空 INVALID_LOG_TOPIC: 11045, // 日志主题长度必须在1到128之间 INVALID_LOG_DATA: 11046, // 日志数据长度必须在1到1024之间 INVALID_CONTRACT_TYPE: 11047 // 无效的合约类型 }; ``` ### 交易相关错误 (11048-11058) ```javascript const TransactionErrors = { INVALID_NONCE: 11048, // Nonce必须在1和int64最大值之间 INVALID_GAS_PRICE: 11049, // GasPrice必须在1和int64最大值之间 INVALID_FEE_LIMIT: 11050, // FeeLimit必须在1和int64最大值之间 EMPTY_OPERATIONS: 11051, // 操作不能为空 INVALID_SIGNATURE: 11054, // 签名数量必须在1和int32最大值之间 INVALID_HASH: 11055, // 无效的交易哈希 INVALID_BLOB: 11056, // 无效的blob EMPTY_PRIVATE_KEY: 11057, // 私钥不能为空 INVALID_PRIVATE_KEY: 11058 // 私钥中存在无效值 }; ``` ### 网络错误 ```javascript const NetworkErrors = { NETWORK_ERROR: 11007, // 网络连接失败 CONNECT_BLOCKCHAIN: 19999, // 连接区块链失败 SYSTEM_ERROR: 20000 // 系统错误 }; ``` ## 错误处理最佳实践 ### 1. 统一错误处理工具 ```javascript // 错误处理工具类 class ErrorHandler { static isSuccess(response) { return response && response.errorCode === 0; } static getErrorMessage(response) { if (!response) return '无响应'; return `[${response.errorCode}] ${response.errorDesc}`; } static async handleResponse(promise) { try { const response = await promise; if (!this.isSuccess(response)) { throw new Error(this.getErrorMessage(response)); } return response.result; } catch (error) { console.error('操作失败:', error); throw error; } } } // 使用示例 async function getAccountInfo(address) { return ErrorHandler.handleResponse( sdk.account.getInfo(address) ); } ``` ### 2. 重试机制 ```javascript // 带重试的操作执行器 async function retryOperation(operation, maxRetries = 3, delay = 1000) { let lastError; for (let i = 0; i < maxRetries; i++) { try { const response = await operation(); if (response.errorCode === 0) { return response.result; } // 对特定错误进行重试 if ([11007, 19999].includes(response.errorCode)) { lastError = new Error(response.errorDesc); await new Promise(resolve => setTimeout(resolve, delay * (i + 1))); continue; } throw new Error(`[${response.errorCode}] ${response.errorDesc}`); } catch (error) { lastError = error; // 网络错误重试 if (error.message.includes('network')) { await new Promise(resolve => setTimeout(resolve, delay * (i + 1))); continue; } throw error; } } throw lastError; } // 使用示例 async function safeGetAccountInfo(address) { return retryOperation(() => sdk.account.getInfo(address)); } ``` ### 3. 错误分类处理 ```javascript // 错误分类处理器 class ErrorClassifier { static classify(errorCode) { if (errorCode >= 11001 && errorCode <= 11006) { return 'ACCOUNT_ERROR'; } if (errorCode >= 11030 && errorCode <= 11043) { return 'TOKEN_ERROR'; } if (errorCode >= 11048 && errorCode <= 11058) { return 'TRANSACTION_ERROR'; } if ([11007, 19999].includes(errorCode)) { return 'NETWORK_ERROR'; } return 'UNKNOWN_ERROR'; } static handle(error) { const errorCode = error.code || parseInt(error.message.match(/\[(\d+)\]/)?.[1]); const errorType = this.classify(errorCode); switch (errorType) { case 'ACCOUNT_ERROR': // 处理账户相关错误 console.error('账户操作错误:', error.message); break; case 'TOKEN_ERROR': // 处理Token相关错误 console.error('Token操作错误:', error.message); break; case 'TRANSACTION_ERROR': // 处理交易相关错误 console.error('交易操作错误:', error.message); break; case 'NETWORK_ERROR': // 处理网络相关错误 console.error('网络错误:', error.message); break; default: // 处理未知错误 console.error('未知错误:', error.message); } } } ``` ### 4. 日志记录 ```javascript // 错误日志记录器 class ErrorLogger { static log(error, context = {}) { const errorInfo = { timestamp: new Date().toISOString(), errorCode: error.code, errorMessage: error.message, stack: error.stack, context: context }; console.error('错误日志:', JSON.stringify(errorInfo, null, 2)); // 可以添加将日志保存到文件或发送到日志服务器的逻辑 } static async logOperation(operation, context) { try { return await operation(); } catch (error) { this.log(error, context); throw error; } } } // 使用示例 async function transferAsset(params) { return ErrorLogger.logOperation( () => sdk.operation.asset.pay(params), { operation: 'transferAsset', params } ); } ``` ### 5. 错误恢复策略 ```javascript // 错误恢复策略 class ErrorRecoveryStrategy { static async recover(error, operation, context) { const errorType = ErrorClassifier.classify(error.code); switch (errorType) { case 'NETWORK_ERROR': // 网络错误恢复策略 return await this.handleNetworkError(operation); case 'TRANSACTION_ERROR': // 交易错误恢复策略 return await this.handleTransactionError(operation, context); default: throw error; } } static async handleNetworkError(operation) { return retryOperation(operation); } static async handleTransactionError(operation, context) { // 检查nonce是否正确 if (context.sourceAddress) { const accountInfo = await sdk.account.getInfo(context.sourceAddress); context.nonce = accountInfo.result.nonce; } return operation(context); } } // 使用示例 async function safeOperation(operation, context) { try { return await operation(context); } catch (error) { return await ErrorRecoveryStrategy.recover(error, operation, context); } } ```