Skip to main content

错误代码 (Error Codes)

ZTDX API 使用标准的 HTTP 状态码和自定义错误代码来指示请求的成功或失败状态。

HTTP 状态码

状态码说明常见原因
200OK请求成功
400Bad Request参数错误、业务逻辑违规
401Unauthorized未授权、JWT过期、签名验证失败
403Forbidden无权访问该资源
404Not Found资源不存在
429Too Many Requests触发频率限制
500Internal Server Error服务器内部错误
503Service Unavailable服务暂时不可用(维护中)

错误响应格式

所有错误都以统一的 JSON 格式返回:

{
"error": "余额不足,需要 653.25 USDT 作为保证金",
"code": "INSUFFICIENT_BALANCE",
"details": {
"required": "653.25",
"available": "500.00",
"token": "USDT"
}
}

字段说明

字段类型描述
errorstring人类可读的错误描述
codestring错误代码(UPPER_SNAKE_CASE)
detailsobject可选的错误详情

认证相关错误

INVALID_SIGNATURE_FORMAT

HTTP状态码: 400
描述: 签名格式无效

原因:

  • 签名不是有效的十六进制字符串
  • 签名长度不正确
  • 缺少 0x 前缀(如果需要)

解决方案:

// ✅ 正确
signature: "0xabcdef123456..." // 0x开头,130个字符

// ❌ 错误
signature: "abcdef123456..." // 缺少0x
signature: "0x123" // 长度不足

SIGNATURE_INVALID

HTTP状态码: 401
描述: EIP-712 签名验证失败

原因:

  • 签名使用了错误的私钥
  • TypedData 结构不匹配
  • Domain 配置不正确
  • Timestamp 不匹配

解决方案:

// 检查 Domain
const domain = {
name: "ZTDX",
version: "1",
chainId: 421614, // 确保正确
verifyingContract: vaultAddress // 确保正确
};

// 检查 Timestamp
const timestamp = Math.floor(Date.now() / 1000); // 秒级

TIMESTAMP_EXPIRED

HTTP状态码: 400
描述: 时间戳已过期(超过5分钟)

解决方案:

// 始终使用最新的时间戳
const timestamp = Math.floor(Date.now() / 1000);

NONCE_INVALID

HTTP状态码: 400
描述: Nonce 无效或已使用

解决方案:

// 重新获取 nonce
const { nonce } = await fetch(`/api/v1/auth/nonce/${address}`).then(r => r.json());

TOKEN_EXPIRED

HTTP状态码: 401
描述: JWT Token 已过期

解决方案:

// 重新登录获取新 token
await login(address, signature, timestamp);

TOKEN_INVALID

HTTP状态码: 401
描述: JWT Token 无效或格式错误

解决方案:

// 确保 token 格式正确
headers: {
'Authorization': `Bearer ${token}` // 注意 Bearer 前缀
}

订单相关错误

INSUFFICIENT_BALANCE

HTTP状态码: 400
描述: 可用余额不足

详情:

{
"error": "余额不足,需要 653.25 USDT 作为保证金",
"code": "INSUFFICIENT_BALANCE",
"details": {
"required": "653.25",
"available": "500.00"
}
}

解决方案:

  • 充值更多资金
  • 降低订单数量
  • 增加杠杆倍数(谨慎)

INVALID_SYMBOL

HTTP状态码: 400
描述: 不支持的交易对

解决方案:

// 查询支持的交易对
const markets = await fetch('/api/v1/markets').then(r => r.json());

INVALID_LEVERAGE

HTTP状态码: 400
描述: 杠杆倍数超出范围(1-50)

解决方案:

// 确保杠杆在有效范围内
const leverage = Math.min(Math.max(userLeverage, 1), 50);

INVALID_AMOUNT

HTTP状态码: 400
描述: 订单数量无效

原因:

  • 数量 <= 0
  • 数量小于最小订单量
  • 数量超过最大订单量

解决方案:

// 检查市场配置
const market = await getMarket('BTCUSDT');
if (amount < parseFloat(market.min_order_size)) {
throw new Error('数量小于最小订单量');
}

PRICE_REQUIRED

HTTP状态码: 400
描述: 限价单必须指定价格

解决方案:

// 限价单必须有价格
{
order_type: "limit",
price: "65000.00" // 必填
}

// 市价单不需要价格
{
order_type: "market"
// price 不填或填null
}

ORDER_NOT_FOUND

HTTP状态码: 404
描述: 订单不存在

原因:

  • 订单ID错误
  • 订单已被删除

ORDER_NOT_CANCELLABLE

HTTP状态码: 400
描述: 订单状态不允许取消

原因:

  • 订单已完全成交(filled
  • 订单已取消(cancelled
  • 订单已拒绝(rejected

解决方案:

// 检查订单状态
const order = await getOrder(orderId);
if (['open', 'pending', 'partially_filled'].includes(order.status)) {
await cancelOrder(orderId);
} else {
console.log('订单不可取消');
}

ORDER_NOT_OWNED

HTTP状态码: 403
描述: 无权操作此订单(不属于当前用户)


仓位相关错误

POSITION_NOT_FOUND

HTTP状态码: 404
描述: 仓位不存在

POSITION_NOT_OWNED

HTTP状态码: 403
描述: 无权操作此仓位

INSUFFICIENT_COLLATERAL

HTTP状态码: 400
描述: 减少保证金后,剩余保证金不足

解决方案:

// 检查清算状态
const liq = await getLiquidationStatus(positionId);
const maxRemovable = position.collateral - liq.min_collateral_usd;

LIQUIDATION_RISK

HTTP状态码: 400
描述: 操作后健康系数过低,接近清算

解决方案:

  • 减少移除的保证金数量
  • 先增加保证金再操作

触发订单相关错误

INVALID_TRIGGER_PRICE

HTTP状态码: 400
描述: 触发价格无效

原因:

  • 多仓的止盈价格 <= 当前价格
  • 多仓的止损价格 >= 当前价格
  • 空仓的止盈价格 >= 当前价格
  • 空仓的止损价格 <= 当前价格

解决方案:

// 多仓
if (position.side === 'long') {
takeProfitPrice > markPrice; // ✅
stopLossPrice < markPrice; // ✅
}

// 空仓
if (position.side === 'short') {
takeProfitPrice < markPrice; // ✅
stopLossPrice > markPrice; // ✅
}

TRIGGER_ORDER_NOT_FOUND

HTTP状态码: 404
描述: 触发订单不存在

TRIGGER_ORDER_NOT_CANCELLABLE

HTTP状态码: 400
描述: 触发订单不可取消(已触发或已取消)


推荐相关错误

CODE_ALREADY_EXISTS

HTTP状态码: 409
描述: 用户已有推荐码

解决方案:

// 查询现有推荐码
const dashboard = await get('/api/v1/referral/dashboard');
console.log('您的推荐码:', dashboard.referral_code);

CODE_NOT_FOUND

HTTP状态码: 404
描述: 推荐码不存在

ALREADY_BOUND

HTTP状态码: 409
描述: 已绑定推荐人,不可更改

SELF_REFERRAL

HTTP状态码: 400
描述: 不能使用自己的推荐码

NO_PENDING_EARNINGS

HTTP状态码: 400
描述: 没有待领取的佣金

BELOW_MINIMUM

HTTP状态码: 400
描述: 低于最低领取金额(10 USDT)


充值提现相关错误

INVALID_TOKEN

HTTP状态码: 400
描述: 不支持的代币

解决方案:

// 当前仅支持 USDT
const supportedTokens = ['USDT'];

INVALID_AMOUNT

HTTP状态码: 400
描述: 金额无效(< 最小金额或 > 最大金额)

最小金额:

  • 充值: 10 USDT
  • 提现: 10 USDT

WITHDRAW_NOT_FOUND

HTTP状态码: 404
描述: 提现记录不存在

WITHDRAW_NOT_CANCELLABLE

HTTP状态码: 400
描述: 提现不可取消(已确认或已完成)

可取消状态: pending
不可取消: processing, completed, failed, cancelled


系统相关错误

DATABASE_ERROR

HTTP状态码: 500
描述: 数据库错误

解决方案: 稍后重试

MATCHING_ERROR

HTTP状态码: 500
描述: 撮合引擎错误

解决方案: 稍后重试

RATE_LIMIT_EXCEEDED

HTTP状态码: 429
描述: 超过频率限制

限制:

  • 公开接口: 100次/分钟
  • 私有接口: 60次/分钟
  • 订单操作: 20次/秒

解决方案:

// 实现指数退避重试
async function retryWithBackoff(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.code === 'RATE_LIMIT_EXCEEDED' && i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
}

SERVICE_UNAVAILABLE

HTTP状态码: 503
描述: 服务暂时不可用(维护中)

解决方案: 等待服务恢复,关注公告


错误处理最佳实践

1. 统一错误处理

class ZTDXAPIError extends Error {
constructor(response) {
super(response.error);
this.code = response.code;
this.details = response.details;
this.name = 'ZTDXAPIError';
}
}

async function apiCall(url, options) {
const response = await fetch(url, options);
const data = await response.json();

if (!response.ok) {
throw new ZTDXAPIError(data);
}

return data;
}

// 使用
try {
const order = await apiCall('/api/v1/orders', {
method: 'POST',
body: JSON.stringify(orderData)
});
} catch (error) {
if (error instanceof ZTDXAPIError) {
console.error('API错误:', error.code, error.message);
console.error('详情:', error.details);
} else {
console.error('网络错误:', error);
}
}

2. 特定错误处理

async function createOrderWithErrorHandling(orderData) {
try {
return await createOrder(orderData);
} catch (error) {
switch (error.code) {
case 'INSUFFICIENT_BALANCE':
alert('余额不足,请先充值');
navigateTo('/deposit');
break;

case 'TIMESTAMP_EXPIRED':
// 自动重试
console.log('时间戳过期,重试中...');
orderData.timestamp = Math.floor(Date.now() / 1000);
return createOrderWithErrorHandling(orderData);

case 'SIGNATURE_INVALID':
alert('签名验证失败,请重新登录');
logout();
break;

case 'INVALID_LEVERAGE':
alert(`杠杆倍数必须在 1-${error.details.max_leverage} 之间`);
break;

default:
alert(`创建订单失败: ${error.message}`);
}
throw error;
}
}

3. 用户友好的错误提示

const errorMessages = {
'INSUFFICIENT_BALANCE': '余额不足,请先充值',
'INVALID_SYMBOL': '不支持此交易对',
'TIMESTAMP_EXPIRED': '请求超时,请重试',
'SIGNATURE_INVALID': '签名验证失败,请重新登录',
'ORDER_NOT_FOUND': '订单不存在',
'RATE_LIMIT_EXCEEDED': '请求过于频繁,请稍后再试'
};

function showError(error) {
const message = errorMessages[error.code] || error.message || '未知错误';
toast.error(message);
}

4. 日志记录

function logError(error, context) {
console.error('[ZTDX API Error]', {
code: error.code,
message: error.message,
details: error.details,
context,
timestamp: new Date().toISOString(),
userAgent: navigator.userAgent
});

// 发送到日志服务
logService.error({
source: 'ztdx-api',
error: error.code,
message: error.message,
context
});
}

常见错误场景

场景 1: 首次使用签名失败

错误: SIGNATURE_INVALID

检查清单:

  • Domain 配置是否正确(name, version, chainId, verifyingContract)
  • TypedData 结构是否匹配
  • Timestamp 是否为秒级(不是毫秒)
  • 地址是否小写
  • 私钥是否正确

场景 2: 创建订单余额不足

错误: INSUFFICIENT_BALANCE

解决方案:

  1. 检查可用余额
  2. 计算所需保证金
  3. 充值或调整订单参数
const { available } = await getBalance('USDT');
const requiredMargin = (amount * price) / leverage + fee;

if (parseFloat(available) < requiredMargin) {
console.log(`需要充值 ${requiredMargin - parseFloat(available)} USDT`);
}

场景 3: WebSocket 认证失败

错误: AUTH_FAILED

解决方案:

  1. 检查 WebSocketAuth 签名
  2. 确保使用最新时间戳
  3. 重新建立连接

完整错误代码列表

认证 (AUTH_*)

  • INVALID_SIGNATURE_FORMAT
  • SIGNATURE_INVALID
  • TIMESTAMP_EXPIRED
  • NONCE_INVALID
  • TOKEN_EXPIRED
  • TOKEN_INVALID
  • AUTH_FAILED
  • AUTH_REQUIRED

订单 (ORDER_*)

  • INSUFFICIENT_BALANCE
  • INVALID_SYMBOL
  • INVALID_LEVERAGE
  • INVALID_AMOUNT
  • PRICE_REQUIRED
  • ORDER_NOT_FOUND
  • ORDER_NOT_CANCELLABLE
  • ORDER_NOT_OWNED

仓位 (POSITION_*)

  • POSITION_NOT_FOUND
  • POSITION_NOT_OWNED
  • INSUFFICIENT_COLLATERAL
  • LIQUIDATION_RISK

触发订单 (TRIGGER_*)

  • INVALID_TRIGGER_PRICE
  • TRIGGER_ORDER_NOT_FOUND
  • TRIGGER_ORDER_NOT_CANCELLABLE

推荐 (REFERRAL_*)

  • CODE_ALREADY_EXISTS
  • CODE_NOT_FOUND
  • ALREADY_BOUND
  • SELF_REFERRAL
  • NO_PENDING_EARNINGS
  • BELOW_MINIMUM

充提 (WITHDRAW_/DEPOSIT_)

  • INVALID_TOKEN
  • INVALID_AMOUNT
  • WITHDRAW_NOT_FOUND
  • WITHDRAW_NOT_CANCELLABLE

系统 (SYSTEM_*)

  • DATABASE_ERROR
  • MATCHING_ERROR
  • RATE_LIMIT_EXCEEDED
  • SERVICE_UNAVAILABLE
  • INVALID_CHANNEL (WebSocket)

相关文档