跳到主要内容

错误代码 (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)

相关文档​