# 错误处理

> Shoplazza CLI 如何用 JSON 成功与错误信封、退出码报告失败，以及脚本或智能体该分别怎么处理。

Shoplazza CLI 如何报告失败,以及如何在脚本与智能体中处理。

## 成功与错误信封

成功时,数据以 JSON 信封输出到 **stdout**:

```json
{ "ok": true, "data": { } }
```

失败时,错误信封输出到 **stderr**:

```json
{ "ok": false, "error": { "type": "api", "message": "Product not found", "detail": { "status_code": 404, "request_id": "req_abc123" } } }
```

在交互式终端中使用 `pretty` 或 `table` 输出时,同一错误改为显示易读的 `Error:` 行(有则附带 `Hint:` 与 `Request ID:` 行)。stderr 被管道或重定向,以及 `json`、`ndjson`、`csv` 输出(管道、CI 或 `--no-input` 下默认就是 `json`)时,始终输出 JSON 信封。

有 `hint` 时务必读——它告诉你下一步。保留 `error.detail.request_id` 以便求助。完整结构见[错误格式](../reference/error-format)。

## 退出码

按退出码分支,而不是解析文本:

| 码 | 类型 | 常见处理 |
|----|------|---------|
| `0` | 成功 | — |
| `1` | API 错误 | 检查 `error.message` / `error.detail.request_id` |
| `2` | 校验错误 | 修正 flag 或输入 JSON |
| `3` | 认证错误 | `shoplazza auth login` |
| `4` | 网络错误 | 检查连通性,重试 |
| `5` | 内部错误 | 上报 bug |
| `130` | 已取消 | 在终端中拒绝了提示或确认——无需处理 |

```shell
shoplazza products list
case $? in
  0) echo "ok" ;;
  3) shoplazza auth login --store-domain my-store.myshoplaza.com --domain products ;;
  4) echo "network — retrying"; sleep 2; shoplazza products list ;;
  *) echo "failed (code $?)" ;;
esac
```

完整表见[退出码](../reference/exit-codes)。

## 写操作前先预览

任何写操作,执行前用 `--dry-run` 预览请求:

```shell
shoplazza discounts +percent-code --target order --percent 20 --code SAVE20 --dry-run
```

在交互式终端中,破坏性命令(删除、取消、`orders +refund`、`products +unpublish`、`themes push` 等)发出写请求前还会请你确认。脚本、CI、智能体和 `--dry-run` 不会被提示。

## 重试

只重试瞬时失败(网络 `4`;部分 `1` 限流响应)。不要盲目重试校验(`2`)或认证(`3`)错误——先修因。在 CI 中限制重试次数并退避。

## 参见

* [退出码](../reference/exit-codes)
* [错误格式](../reference/error-format)
* [输出格式](./output-formats)
