Goal
判断一次失败属于 Access、Quota、Usage Inspector 还是 Provider 层。
Outcome
你能回答“Provider 是否被调用”“是否应该重试”“应该使用哪个 Request ID”,而不是只按 HTTP 状态猜测。
Prerequisites
- 客户端响应中的
x-nexus-request-id或 JSONerror.request_id。 - Workspace ID、Access ID 和只在后端使用的 Management Key。
Lifecycle note
Quota Snapshot 是当前 Period 的投影,UsageEvent 是不可变结算事实,Invocation/Provider Attempt 是一次请求事实。它们不能互相替代。
1. Collect the current facts
const baseUrl = required('NEXUS_ADMIN_BASE_URL').replace(/\/$/, '');
const key = required('NEXUS_MANAGEMENT_KEY');
const workspaceId = required('NEXUS_WORKSPACE_ID');
const accessId = required('NEXUS_ACCESS_ID');
const requestId = process.env.NEXUS_REQUEST_ID?.trim();
async function get(path) {
const response = await fetch(`${baseUrl}${path}`, { headers: { Authorization: `Bearer ${key}` } });
if (!response.ok) throw new Error(`GET ${path} failed: ${response.status} ${await response.text()}`);
return response.json();
}
const [quota, invocations, usageEvents] = await Promise.all([
get(`/admin/v1/workspace-accesses/${accessId}/quota`),
get(`/admin/v1/workspaces/${workspaceId}/invocations`),
get(`/admin/v1/workspaces/${workspaceId}/usage-events`),
]);
const invocation = requestId ? invocations.find((item) => item.requestId === requestId) : undefined;
console.log(
JSON.stringify(
{
quota,
invocation,
usageEvents: invocation ? usageEvents.filter((item) => item.invocationId === invocation.id) : [],
},
null,
2,
),
);
function required(name) {
const value = process.env[name]?.trim();
if (!value) throw new Error(`${name} is required`);
return value;
}2. Classify the failure
| Signal | Layer | Provider called? | Retry guidance |
|---|---|---|---|
workspace_access_denied |
Access | No | Fix status/expiry; do not retry unchanged |
quota_exceeded |
Quota admission | No | Wait for reset_at or change entitlement |
metering_unsupported |
Usage Inspector | No | Use a supported endpoint; do not retry unchanged |
access_unavailable |
PostgreSQL/Access service | No | Retry with backoff after service recovery |
provider_connection_not_found |
Workspace connection resolution | No | Fix UUID/status; do not retry unchanged |
provider_unavailable / provider timeout |
Provider transport | Yes or attempted | Check Provider Attempt, then bounded retry |
| Upstream non-2xx body | Provider | Yes | Follow upstream semantics and preserve Request ID |
Check your work
availableUnits = grantedUnits - consumedUnits - reservedUnits。如果请求被 admission 拒绝,不应出现 Provider Attempt;如果 Provider 已开始响应,应有 Invocation/Attempt,并最终有结算或释放事实。
Failure modes
- 找不到 Invocation:优先确认使用的是 Gateway
x-nexus-request-id,不是 Admin API 请求 ID。 reservedUnits长时间不下降:检查 Worker 健康、过期 Reservation recovery 和同一 Invocation 的事件。- Usage 为零:区分 Provider 合法报告零、Inspector 未识别和请求根本未到 Provider。
Security notes
诊断输出不得包含 Authorization、Provider Secret 或完整敏感请求正文。共享事件时使用 Request ID 和资源 ID。
Next steps
查看完整 Troubleshooting matrix;需要余额语义时阅读 Quota periods。