ErrorTable.kt
// Generated by tools/gen-errors.mjs from spec/errors.json version 2026-10-08. Do not edit.
package com.shengzhiai.yugu.errors
/** Error, warning and local code tables. */
object ErrorTable {
data class Entry(
val code: Int,
val name: String,
val category: String,
val retryable: Boolean,
val http: Int,
val message: String,
)
val ERRORS: Map<Int, Entry> = listOf(
Entry(40001, "VALIDATION_ERROR", "INVALID_PARAM", false, 400, "请求参数校验失败"),
Entry(40100, "UNAUTHORIZED", "AUTH", false, 401, "未认证,缺少或无效的凭据"),
Entry(40300, "FORBIDDEN", "PERMISSION", false, 403, "无权限,例如 API Key 未授权该 coreType"),
Entry(40400, "NOT_FOUND", "NOT_FOUND", false, 404, "资源不存在"),
Entry(40900, "CONFLICT", "CONFLICT", false, 409, "资源冲突"),
Entry(40901, "IDEMPOTENCY_IN_PROGRESS", "CONFLICT", true, 409, "同一幂等键的请求仍在处理中,稍后用同一个键重试"),
Entry(40902, "QUOTA_INSUFFICIENT", "QUOTA", false, 409, "套餐额度和账户余额均不足"),
Entry(40903, "IDEMPOTENCY_KEY_REUSED", "CONFLICT", false, 409, "幂等键已用于另一个不同的请求"),
Entry(42900, "TOO_MANY_REQUESTS", "RATE_LIMIT", true, 429, "请求过多或评测排队超时,按 Retry-After 稍后重试"),
Entry(42901, "CONCURRENCY_LIMIT", "RATE_LIMIT", true, 429, "并发评测数超出套餐层级限制"),
Entry(42902, "TRIAL_REPORT_DAILY_LIMIT", "QUOTA", false, 429, "试用层 AI 报告达到每日上限"),
Entry(42903, "SANDBOX_DAILY_LIMIT", "QUOTA", false, 429, "沙箱密钥当日调用次数达到上限"),
Entry(50000, "INTERNAL_ERROR", "SERVER", true, 500, "服务器内部错误"),
Entry(50010, "FEATURE_NOT_IMPLEMENTED", "SERVER", false, 500, "功能未实现"),
Entry(50200, "UPSTREAM_SERVICE_ERROR", "UPSTREAM", true, 502, "上游评测服务暂不可用"),
Entry(2001, "TOKEN_EXPIRED", "AUTH", false, 401, "token 已过期,兼容层早期引擎接口也用此码表示缺少鉴权三元组或签名不匹配"),
Entry(2002, "TOKEN_INVALID", "AUTH", false, 401, "token 无效,兼容层早期引擎接口也用此码表示时间戳超窗"),
Entry(2003, "SIGNATURE_VERIFICATION_FAILED", "AUTH", false, 401, "签名验证失败,兼容层早期引擎接口也用此码表示 appKey 不存在"),
Entry(2004, "SESSION_EXPIRED", "AUTH", false, 401, "会话已过期"),
Entry(2005, "TOKEN_BLACKLISTED", "AUTH", false, 401, "token 已被列入黑名单"),
Entry(2006, "API_KEY_INVALID", "AUTH", false, 401, "API Key 无效"),
Entry(2007, "API_KEY_EXPIRED", "AUTH", false, 401, "API Key 已过期"),
Entry(2008, "TOKEN_METADATA_NOT_FOUND", "AUTH", false, 401, "token 元数据丢失"),
Entry(2009, "TOKEN_REFRESH_FAILED", "AUTH", false, 401, "token 刷新失败"),
Entry(2010, "API_KEY_NOT_FOUND", "AUTH", false, 401, "API Key 不存在"),
Entry(2011, "API_KEY_DISABLED", "AUTH", false, 401, "API Key 已禁用"),
Entry(2012, "API_KEY_QUOTA_EXCEEDED", "QUOTA", false, 400, "API Key 配额已超限"),
Entry(3001, "RATE_LIMIT_EXCEEDED_IP", "RATE_LIMIT", true, 429, "请求过于频繁,按来源地址限流"),
Entry(3002, "RATE_LIMIT_EXCEEDED_USER", "RATE_LIMIT", true, 429, "请求过于频繁,按用户限流"),
Entry(3003, "RATE_LIMIT_EXCEEDED_API_KEY", "RATE_LIMIT", true, 429, "请求过于频繁,按 API Key 限流"),
Entry(1004, "USER_DISABLED", "PERMISSION", false, 400, "用户已禁用"),
Entry(1005, "USER_LOCKED", "PERMISSION", false, 400, "用户已锁定"),
Entry(1012, "ACCOUNT_DISABLED", "PERMISSION", false, 400, "账户已禁用"),
Entry(1013, "ACCOUNT_FROZEN", "PERMISSION", false, 400, "账户已冻结"),
Entry(1310, "ACCOUNT_BALANCE_INSUFFICIENT", "QUOTA", false, 400, "账户余额不足"),
Entry(1311, "ACCOUNT_LEDGER_CONFLICT", "CONFLICT", true, 400, "账目并发冲突,重试即可"),
).associateBy { it.code }
val WARNINGS: Map<Int, Entry> = listOf(
Entry(1001, "NO_VALID_AUDIO", "AUDIO", false, 0, "No valid audio detected!"),
Entry(1002, "VOLUME_TOO_LOW", "AUDIO", false, 0, "Audio volume too low!"),
Entry(1003, "VOLUME_TOO_HIGH", "AUDIO", false, 0, "Audio volume too high!"),
Entry(1004, "AUDIO_NOISY", "AUDIO", false, 0, "Audio noisy!"),
Entry(1005, "AUDIO_INCOMPLETE", "AUDIO", false, 0, "Audio not complete!"),
Entry(1009, "SCORER_DEGRADED", "AUDIO", true, 0, "scorer degraded"),
).associateBy { it.code }
val LOCAL: Map<Int, Entry> = listOf(
Entry(90001, "NETWORK_ERROR", "NETWORK", true, 0, "网络错误,连接失败或被重置"),
Entry(90002, "TIMEOUT", "TIMEOUT", true, 0, "连接或读取超时"),
Entry(90003, "CANCELLED", "CANCELLED", false, 0, "调用方取消了请求"),
Entry(90004, "CLIENT_CLOSED", "STATE", false, 0, "客户端已关闭"),
Entry(90005, "PROTOCOL_ERROR", "PROTOCOL", false, 0, "响应或帧无法解析"),
Entry(90006, "RECONNECT_EXHAUSTED", "NETWORK", false, 0, "实时连接重连次数用尽"),
Entry(90007, "RESULT_TIMEOUT", "TIMEOUT", true, 0, "结束后等待终评结果超时"),
Entry(90008, "REPLAY_BUFFER_OVERFLOW", "STATE", false, 0, "重连重放缓冲超过上限"),
Entry(90009, "INVALID_STATE", "STATE", false, 0, "当前会话状态不允许该操作"),
Entry(90010, "INVALID_ARGUMENT", "INVALID_PARAM", false, 0, "调用参数不合法"),
Entry(90011, "TLS_ERROR", "NETWORK", false, 0, "证书校验失败"),
Entry(90101, "AUDIO_TOO_SHORT", "AUDIO", false, 0, "音频短于 1 秒"),
Entry(90102, "AUDIO_TOO_LONG", "AUDIO", false, 0, "音频长于 300 秒,整段上传大于 50 MB,或实时评测一轮大于 10 MB"),
Entry(90103, "AUDIO_SILENT", "AUDIO", false, 0, "音频全程静音"),
Entry(90104, "AUDIO_LOW_VOLUME", "AUDIO", false, 0, "音量过低"),
Entry(90105, "AUDIO_FORMAT_UNSUPPORTED", "AUDIO", false, 0, "不是 16 位 PCM 或采样率低于 16000"),
Entry(90201, "RECORDER_PERMISSION_DENIED", "PERMISSION", false, 0, "没有麦克风权限"),
Entry(90202, "RECORDER_UNAVAILABLE", "STATE", false, 0, "麦克风被占用或不可用"),
Entry(90203, "RECORDER_ERROR", "STATE", false, 0, "录音过程出错"),
).associateBy { it.code }
val HTTP_FALLBACK: Map<Int, String> = mapOf(
400 to "INVALID_PARAM",
401 to "AUTH",
403 to "PERMISSION",
404 to "NOT_FOUND",
405 to "INVALID_PARAM",
408 to "TIMEOUT",
409 to "CONFLICT",
413 to "INVALID_PARAM",
415 to "INVALID_PARAM",
422 to "INVALID_PARAM",
425 to "RATE_LIMIT",
429 to "RATE_LIMIT",
500 to "SERVER",
501 to "SERVER",
502 to "UPSTREAM",
503 to "UPSTREAM",
504 to "UPSTREAM",
)
val RETRYABLE_HTTP: Set<Int> = setOf(408, 425, 429, 500, 502, 503, 504)
}
/** Named code constants. */
object ErrorCodes {
const val VALIDATION_ERROR = 40001
const val UNAUTHORIZED = 40100
const val FORBIDDEN = 40300
const val NOT_FOUND = 40400
const val CONFLICT = 40900
const val IDEMPOTENCY_IN_PROGRESS = 40901
const val QUOTA_INSUFFICIENT = 40902
const val IDEMPOTENCY_KEY_REUSED = 40903
const val TOO_MANY_REQUESTS = 42900
const val CONCURRENCY_LIMIT = 42901
const val TRIAL_REPORT_DAILY_LIMIT = 42902
const val SANDBOX_DAILY_LIMIT = 42903
const val INTERNAL_ERROR = 50000
const val FEATURE_NOT_IMPLEMENTED = 50010
const val UPSTREAM_SERVICE_ERROR = 50200
const val TOKEN_EXPIRED = 2001
const val TOKEN_INVALID = 2002
const val SIGNATURE_VERIFICATION_FAILED = 2003
const val SESSION_EXPIRED = 2004
const val TOKEN_BLACKLISTED = 2005
const val API_KEY_INVALID = 2006
const val API_KEY_EXPIRED = 2007
const val TOKEN_METADATA_NOT_FOUND = 2008
const val TOKEN_REFRESH_FAILED = 2009
const val API_KEY_NOT_FOUND = 2010
const val API_KEY_DISABLED = 2011
const val API_KEY_QUOTA_EXCEEDED = 2012
const val RATE_LIMIT_EXCEEDED_IP = 3001
const val RATE_LIMIT_EXCEEDED_USER = 3002
const val RATE_LIMIT_EXCEEDED_API_KEY = 3003
const val USER_DISABLED = 1004
const val USER_LOCKED = 1005
const val ACCOUNT_DISABLED = 1012
const val ACCOUNT_FROZEN = 1013
const val ACCOUNT_BALANCE_INSUFFICIENT = 1310
const val ACCOUNT_LEDGER_CONFLICT = 1311
const val W_NO_VALID_AUDIO = 1001
const val W_VOLUME_TOO_LOW = 1002
const val W_VOLUME_TOO_HIGH = 1003
const val W_AUDIO_NOISY = 1004
const val W_AUDIO_INCOMPLETE = 1005
const val W_SCORER_DEGRADED = 1009
const val NETWORK_ERROR = 90001
const val TIMEOUT = 90002
const val CANCELLED = 90003
const val CLIENT_CLOSED = 90004
const val PROTOCOL_ERROR = 90005
const val RECONNECT_EXHAUSTED = 90006
const val RESULT_TIMEOUT = 90007
const val REPLAY_BUFFER_OVERFLOW = 90008
const val INVALID_STATE = 90009
const val INVALID_ARGUMENT = 90010
const val TLS_ERROR = 90011
const val AUDIO_TOO_SHORT = 90101
const val AUDIO_TOO_LONG = 90102
const val AUDIO_SILENT = 90103
const val AUDIO_LOW_VOLUME = 90104
const val AUDIO_FORMAT_UNSUPPORTED = 90105
const val RECORDER_PERMISSION_DENIED = 90201
const val RECORDER_UNAVAILABLE = 90202
const val RECORDER_ERROR = 90203
}