iii-error-handling

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Error Handling

错误处理

iii has two broad error classes: SDK/local errors and engine/remote invocation errors. Agents should branch on the error code instead of matching only message strings.
iii包含两大类错误:SDK/本地错误和引擎/远程调用错误。Agent应根据错误代码进行分支处理,而非仅匹配消息字符串。

Error Codes

错误代码

Branch on exact
code
strings, but keep engine wire codes separate from SDK-local codes.
CodeEmitted byMeaningTypical handling
function_not_found
Engine and SDK local dispatchNo registered function is available under that IDCheck function ID, worker install/startup, discovery, and trigger type hints
invocation_error
Engine invocation/router pathEngine failed to route, remember, or complete the invocationInspect engine logs, protocol state, and worker connectivity
invocation_stopped
Engine invocation handlerInvocation was cancelled or stopped by the engine/runtimeTreat as failed work; decide whether caller should retry
FORBIDDEN
RBAC / worker-gated engine functionsRBAC denied the actionDo not retry blindly; inspect policy, auth context, and allowed functions
timeout
Engine/worker wire error when a worker reports lowercase timeoutInvocation exceeded a timeout reported through the wire protocolTreat as timeout, but do not assume every SDK maps it to a timeout subclass
function_not_invokable
SDK local dispatchRegistration exists but cannot be invoked as a normal local functionInspect registration/invocation type
invocation_failed
SDK worker handler wrappersLocal worker handler, HTTP-invoked function wrapper, or SDK-side handler path failedInspect handler logs, stacktrace, and payload validation
TIMEOUT
Node/Python SDK caller timeoutClient waited longer than
trigger()
timeout
Increase timeout only if the workload is expected to run long; otherwise optimize or enqueue
需根据精确的
code
字符串进行分支处理,但需将引擎通信代码与SDK本地代码区分开。
代码触发方含义典型处理方式
function_not_found
引擎及SDK本地调度无已注册函数对应该ID检查函数ID、Worker安装/启动情况、服务发现及触发器类型提示
invocation_error
引擎调用/路由路径引擎无法完成路由、记录或调用操作检查引擎日志、协议状态及Worker连通性
invocation_stopped
引擎调用处理器调用被引擎/运行时取消或终止视为工作失败;判断调用方是否应重试
FORBIDDEN
RBAC / Worker gated引擎功能RBAC拒绝该操作请勿盲目重试;检查策略、认证上下文及允许调用的函数
timeout
引擎/Worker通信错误(Worker报告小写timeout)调用超出了通过通信协议报告的超时时间视为超时,但不要假设所有SDK都将其映射为超时子类
function_not_invokable
SDK本地调度已存在注册信息,但无法作为常规本地函数调用检查注册/调用类型
invocation_failed
SDK Worker处理器包装器本地Worker处理器、HTTP调用函数包装器或SDK侧处理器路径执行失败检查处理器日志、堆栈跟踪及负载验证
TIMEOUT
Node/Python SDK调用方超时客户端等待时间超过
trigger()
超时设置
仅当预期工作负载运行时间较长时才增加超时时间;否则优化或加入队列

Handler vs Engine Errors

处理器错误 vs 引擎错误

  • Handler errors originate in user function code, SDK local dispatch, or HTTP-invoked endpoints.
  • Engine errors originate in routing, invocation state, RBAC, protocol handling, or worker-reported wire errors.
  • Queue retries only apply to enqueued work. Synchronous failures are returned directly to the caller.
  • Void dispatch does not return handler results, so use logs/observability for failures.
  • 处理器错误源于用户函数代码、SDK本地调度或HTTP调用端点。
  • 引擎错误源于路由、调用状态、RBAC、协议处理或Worker报告的通信错误。
  • 队列重试仅适用于已加入队列的工作。同步失败将直接返回给调用方。
  • Void调度不返回处理器结果,因此需通过日志/可观测性排查故障。

Retryability

重试机制

  • Retry transient
    timeout
    ,
    TIMEOUT
    , transport, or worker reconnect failures only when the operation is idempotent.
  • Do not retry
    FORBIDDEN
    without changing auth/policy.
  • Do not retry
    function_not_found
    by calling the same ID repeatedly; discover functions or install/start the missing worker.
  • For reliable background work, use
    TriggerAction.Enqueue({ queue })
    and queue retry/DLQ policy.
  • 仅当操作具有幂等性时,才重试短暂的
    timeout
    TIMEOUT
    、传输或Worker重连失败。
  • 在未更改认证/策略的情况下,请勿重试
    FORBIDDEN
    错误。
  • 请勿通过重复调用同一ID来重试
    function_not_found
    错误;需发现函数或安装/启动缺失的Worker。
  • 如需可靠的后台工作,请使用
    TriggerAction.Enqueue({ queue })
    及队列重试/死信队列(DLQ)策略。

SDK Surfaces

SDK使用示例

Node

Node

typescript
import { IIIInvocationError } from 'iii-sdk'

try {
  await iii.trigger({ function_id: 'orders::charge', payload })
} catch (error) {
  if (error instanceof IIIInvocationError && error.code === 'FORBIDDEN') {
    throw new Error('Policy denied orders::charge')
  }
  throw error
}
typescript
import { IIIInvocationError } from 'iii-sdk'

try {
  await iii.trigger({ function_id: 'orders::charge', payload })
} catch (error) {
  if (error instanceof IIIInvocationError && error.code === 'FORBIDDEN') {
    throw new Error('Policy denied orders::charge')
  }
  throw error
}

Python

Python

python
from iii import IIIForbiddenError, IIIInvocationError, IIITimeoutError

try:
    result = iii.trigger({"function_id": "orders::charge", "payload": payload})
except IIIForbiddenError:
    raise RuntimeError("Policy denied orders::charge")
except IIITimeoutError:
    raise RuntimeError("orders::charge timed out")
except IIIInvocationError as exc:
    if exc.code == "timeout":
        raise RuntimeError("orders::charge timed out")
    raise RuntimeError(f"{exc.code}: {exc.message}")
python
from iii import IIIForbiddenError, IIIInvocationError, IIITimeoutError

try:
    result = iii.trigger({"function_id": "orders::charge", "payload": payload})
except IIIForbiddenError:
    raise RuntimeError("Policy denied orders::charge")
except IIITimeoutError:
    raise RuntimeError("orders::charge timed out")
except IIIInvocationError as exc:
    if exc.code == "timeout":
        raise RuntimeError("orders::charge timed out")
    raise RuntimeError(f"{exc.code}: {exc.message}")

Rust

Rust

rust
match iii.trigger(request).await {
    Ok(value) => value,
    Err(iii_sdk::IIIError::Timeout) => {
        return Err("orders::charge timed out".into());
    }
    Err(iii_sdk::IIIError::Remote { code, message, .. }) if code == "FORBIDDEN" => {
        return Err(format!("policy denied: {message}").into());
    }
    Err(err) => return Err(err.into()),
}
rust
match iii.trigger(request).await {
    Ok(value) => value,
    Err(iii_sdk::IIIError::Timeout) => {
        return Err("orders::charge timed out".into());
    }
    Err(iii_sdk::IIIError::Remote { code, message, .. }) if code == "FORBIDDEN" => {
        return Err(format!("policy denied: {message}").into());
    }
    Err(err) => return Err(err.into()),
}

Browser

Browser

Browser trigger calls reject with JavaScript errors. Preserve the engine-provided code/message when present and show policy failures as permission errors in UI.
浏览器触发调用会以JavaScript错误形式拒绝。若存在引擎提供的代码/消息则予以保留,并在UI中将策略失败显示为权限错误。

Pattern Boundaries

模式边界

  • For RBAC policy design, prefer
    iii-worker-rbac
    .
  • For invocation modes and retries, prefer
    iii-trigger-actions
    .
  • For logs/traces around failures, prefer
    iii-observability
    .
  • 对于RBAC策略设计,优先使用
    iii-worker-rbac
  • 对于调用模式和重试,优先使用
    iii-trigger-actions
  • 对于故障相关的日志/追踪,优先使用
    iii-observability

When to Use

使用场景

  • Use this skill when the task mentions iii errors, exception handling, failed invocations, timeouts, forbidden calls, retry behavior, or SDK error classes.
  • 当任务涉及iii错误、异常处理、调用失败、超时、禁止调用、重试行为或SDK错误类时,使用此技能。

Boundaries

边界限制

  • Do not retry non-idempotent work automatically unless it is enqueued under queue policy.
  • Do not treat RBAC denial as a missing worker.
  • Do not generate removed service APIs or adapter-extension APIs.
  • 除非根据队列策略加入队列,否则请勿自动重试非幂等性工作。
  • 请勿将RBAC权限拒绝视为Worker缺失。
  • 请勿生成已移除的服务API或适配器扩展API。