> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squarecloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# エラー

> Go SDK で *APIError を処理します: ステータス、コード、メッセージ、errors.As と errors.Is、SDK 独自のコード、Code 定数、リトライ、タイムアウト、レート制限。

API、ネットワーク、ローカルのすべての失敗は、1 つの型 `*squarecloud.APIError` で表されます。`errors.As` で確認してください。

```go theme={"system"}
package main

import (
	"context"
	"errors"
	"fmt"
	"os"

	"github.com/squarecloudofc/sdk-api-go/v3"
)

func main() {
	ctx := context.Background()
	c := squarecloud.New(os.Getenv("SQUARECLOUD_API_KEY"))
	appID := "abc123def456abc123def456"

	err := c.Apps.Start(ctx, appID)

	var apiErr *squarecloud.APIError
	if errors.As(err, &apiErr) {
		fmt.Println(apiErr.Status, apiErr.Code, apiErr.Message)
		fmt.Println(apiErr.Method, apiErr.Path) // "POST" "/v2/apps/<id>/start"
	}
}
```

## `APIError`

| フィールド     | 型        | 説明                                                                                   |
| --------- | -------- | ------------------------------------------------------------------------------------ |
| `Status`  | `int`    | HTTP ステータス。レスポンスが届かなかった場合 (ネットワークエラー、タイムアウト、ローカルのチェック) は `0`                         |
| `Code`    | `string` | API のエラーコード (例: `APP_NOT_FOUND`)、または SDK 独自のコードのいずれか。[`Code*` 定数](#code-定数)と比較してください |
| `Message` | `string` | サーバーによる説明。サーバーがコードだけを送った場合は `""`                                                     |
| `Method`  | `string` | 失敗した呼び出しの HTTP メソッド                                                                  |
| `Path`    | `string` | 失敗した呼び出しの URL パス (クエリ文字列を除く)                                                         |

`Unwrap()` は、`NETWORK_ERROR`、`TIMEOUT`、無効な JSON の場合はその原因 (トランスポート、デコード、または context のエラー) を返し、それ以外では `nil` を返します。`Error()` は `squarecloud: <METHOD> <path>: HTTP <status> <CODE>: <message>` を出力します。ステータスが `0` の場合は `HTTP <status>` が、メッセージが空の場合は `: <message>` が省かれます。このテキストではなく、フィールドで判定してください。

### キャンセルされた context と期限切れの context

`ctx` がキャンセルされた呼び出しは `NETWORK_ERROR` の `*APIError` を返し、期限を過ぎた呼び出しは `TIMEOUT` を返します。どちらもステータスは `0` です。これらは context のエラーにアンラップされます:

```go theme={"system"}
_, err := c.Apps.Get(ctx, appID)

switch {
case errors.Is(err, context.Canceled):
	// you canceled ctx
case errors.Is(err, context.DeadlineExceeded):
	// the deadline of ctx, or the default one, passed
}
```

いくつかの失敗は `*APIError` ではありません:

* [`Realtime.Next`](/ja/sdks/go/realtime#ストリームの終了) は、その `ctx` が終了すると素の `ctx.Err()` を返し、ストリームが正常に終了すると `io.EOF` を返します。
* 呼び出し側の問題は通常のエラーです: `nil` のアップロードリーダー、解析できない snapshot URL またはベース URL、`encoding/json` でエンコードできない入力、そして `DownloadSnapshot` に渡した `io.Writer` のエラー。

## SDK のコード

| ステータス | コード               | 定数                  | 発生条件                                                                                                                                               |
| ----- | ----------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| 0     | `NETWORK_ERROR`   | `CodeNetworkError`  | レスポンスがない (DNS、接続のリセット、ボディの途中切断)、または `ctx` がキャンセルされた。元のエラーは `Unwrap()` にあります                                                                        |
| 0     | `TIMEOUT`         | `CodeTimeout`       | 期限までにレスポンスがない ([タイムアウト](/ja/sdks/go/client#タイムアウト)を参照)                                                                                             |
| 0     | `FILE_TOO_LARGE`  | `CodeFileTooLarge`  | ローカルのチェック: 100 MB を超えるアップロード、または 10 MB を超える `Files.Write`。何も送信されていません                                                                              |
| 0     | `INVALID_ID`      | `CodeInvalidID`     | ローカルのチェック: 空、`.`、`..` の ID。何も送信されていません                                                                                                             |
| 0     | `INVALID_API_KEY` | `CodeInvalidAPIKey` | ローカルのチェック: クライアントが空のキーで作成された。`Service.Status` 以外のすべての呼び出しで発生します。Go SDK のみ                                                                          |
| 任意    | `UNKNOWN_ERROR`   | `CodeUnknown`       | コードのないレスポンス (プロキシのエラーページなど)。実際の `Status` と、メッセージ `HTTP <status>` を持ちます。JSON ではない 2xx のボディの場合、メッセージは `Invalid JSON in HTTP <status> response` になります |

## `Code*` 定数

`Code` は通常の `string` です。パッケージには、公開されている API コードごとに、Go のスタイルで名付けられた定数が 1 つずつあり (`APP_NOT_FOUND` に対する `CodeAppNotFound`、`CodeInvalidID`、`CodeDNSFailed` など)、さらに上記の SDK 独自のコードもあります。

API コードの一覧は増えていきます。**不明なコードは HTTP ステータスで処理してください**:

```go theme={"system"}
func handle(err error) error {
	var apiErr *squarecloud.APIError
	if !errors.As(err, &apiErr) {
		return err
	}

	switch apiErr.Code {
	case squarecloud.CodeAppNotFound:
		return nil
	case squarecloud.CodeContainerAlreadyStarted:
		return nil // fine
	}
	switch {
	case apiErr.Status == 429:
		return retryLater()
	case apiErr.Status >= 500:
		return reportOutage(apiErr)
	}
	return err
}
```

## すべての呼び出しで発生しうるエラー

| ステータス | コード                     | 発生条件                                                                                  |
| ----- | ----------------------- | ------------------------------------------------------------------------------------- |
| 401   | `ACCESS_DENIED`         | API キーがない、不明、取り消し済み、または期限切れ                                                           |
| 403   | `MISSING_SCOPE`         | キーにこの呼び出しのスコープがない。`Message` にスコープ名が含まれます                                              |
| 403   | `RESOURCE_NOT_ALLOWED`  | キーが別のアプリやデータベースに制限されている                                                               |
| 403   | `PERMISSION_DENIED`     | あなたの workspace のロールではその操作が許可されていない                                                    |
| 404   | `ROUTE_NOT_FOUND`       | 不明なルート                                                                                |
| 429   | `RATE_LIMITED`          | アカウント、キー、または IP のブロック (約 30 分続くことがあります)、およびネットワーク系 endpoint と `Account.Snapshots` の制限 |
| 429   | `KEEP_CALM`             | このルートに対して速すぎる                                                                         |
| 500   | `INTERNAL_SERVER_ERROR` | サーバーエラー                                                                               |
| 503   | `DATABASE_UNAVAILABLE`  | プラットフォームのデータベースが利用できない。変更がすでに適用されている可能性があります                                          |

## グループ別の API コード

<AccordionGroup>
  <Accordion title="見つからない">
    `APP_NOT_FOUND`, `DATABASE_NOT_FOUND`, `WORKSPACE_NOT_FOUND`, `MEMBER_NOT_FOUND`, `FILE_NOT_FOUND`, `SNAPSHOT_NOT_FOUND`, `REPOSITORY_NOT_FOUND`, `BRANCH_NOT_FOUND`, `ROUTE_NOT_FOUND`
  </Accordion>

  <Accordion title="バリデーション">
    `INVALID_ACCESS_TOKEN`, `INVALID_AUTORESTART`, `INVALID_BRANCH_LENGTH`, `INVALID_CODE`, `INVALID_CONTENT`, `INVALID_CONTENT_TYPE`, `INVALID_DATABASE_TYPE`, `INVALID_DATABASE_VERSION`, `INVALID_DESCRIPTION`, `INVALID_DISPLAY_NAME`, `INVALID_DOMAIN`, `INVALID_ENCODING`, `INVALID_ENV_CONTENT`, `INVALID_FILE`, `INVALID_FILENAME`, `INVALID_FILTER`, `INVALID_GROUP`, `INVALID_ID`, `INVALID_INPUT`, `INVALID_JSON_BODY`, `INVALID_MEMORY`, `INVALID_NAME`, `INVALID_PARAMETERS`, `INVALID_PATH`, `INVALID_RESET_TYPE`, `INVALID_SCOPE`, `INVALID_SNAPSHOT_ID`, `INVALID_SUBDOMAIN`, `INVALID_TIME_RANGE`, `INVALID_VERSION_ID`, `MISSING_PARAMETERS`, `MISSING_REQUIRED_FIELDS`, `NO_UPDATE_DATA`, `VALIDATION_FAILED`, `VALIDATION_TIMEOUT`, `ENV_NAME_TOO_LONG`, `ENV_CONTENT_TOO_LONG`, `TOO_MANY_ENV_VARS`, `RESERVED_DOMAIN`, `CANNOT_SET_SUBDOMAIN`, `STATIC_APP_ENV_NOT_SUPPORTED`
  </Accordion>

  <Accordion title="認証と権限">
    `ACCESS_DENIED`, `MISSING_SCOPE`, `RESOURCE_NOT_ALLOWED`, `PERMISSION_DENIED`, `SCOPE_NOT_GRANTABLE`, `BLOCKED_PATH`, `UPGRADE_REQUIRED`
  </Accordion>

  <Accordion title="上限とレート制限">
    `RATE_LIMITED`, `KEEP_CALM`, `APPLICATIONS_LIMIT_REACHED`, `WORKSPACE_LIMIT_REACHED`, `MEMBERS_LIMIT_REACHED`, `LOAD_BALANCER_LIMIT_REACHED`, `DAILY_SNAPSHOTS_LIMIT_REACHED`, `INSUFFICIENT_MEMORY`, `FILE_TOO_LARGE`, `PAYLOAD_TOO_LARGE`, `REALTIME_MAX_CONNECTIONS`, `REALTIME_MAX_CONNECTIONS_APP`, `AI_DAILY_LIMIT_REACHED`, `AI_MAX_CONCURRENT_STREAMS`, `AI_NO_PLAN_LIMIT_REACHED`
  </Accordion>

  <Accordion title="コンテナ (起動、停止、再起動)">
    `CONTAINER_ALREADY_STARTED`, `CONTAINER_ALREADY_STOPPED`, `CONTAINER_TEMPORARILY_SUSPENDED`, `CONTAINER_NOT_FOUND`, `CONTAINER_INSUFFICIENT_DISK_SPACE`, `CONTAINER_NETWORK_CONFLICT`, `ACTION_FAILED`, `DATABASE_NOT_RUNNING`
  </Accordion>

  <Accordion title="アップロード、ファイル、commit">
    `UPLOAD_BUSY`, `UPLOAD_FAILED`, `UPLOAD_ABORTED`, `STORAGE_UPLOAD_FAILED`, `COMMIT_FAILED`, `READ_FAILED`, `SAVE_FAILED`, `RENAME_FAILED`, `DELETE_FAILED`, `REQUEST_ABORTED`, `EMPTY_RESPONSE`
  </Accordion>

  <Accordion title="Snapshot">
    `SNAPSHOT_FAILED`, `SNAPSHOT_PROCESSING`, `SNAPSHOT_RESTORE_FAILED`, `SNAPSHOT_DATABASE_MISMATCH`, `RESTORE_IN_PROGRESS`
  </Accordion>

  <Accordion title="Deploy と GitHub">
    `GIT_ALREADY_CONFIGURED`, `GIT_NOT_CONFIGURED`, `GITHUB_NOT_CONNECTED`, `REPOSITORY_BRANCH_ALREADY_CONFIGURED`, `REPOSITORY_NOT_AVAILABLE`, `REPOSITORY_PERMISSION_REQUIRED`, `FAILED_TO_FETCH`
  </Accordion>

  <Accordion title="ネットワークとドメイン">
    `ANALYTICS_BUSY`, `UNABLE_TO_FETCH_ANALYTICS`, `UNABLE_TO_FETCH_ERRORS`, `UNABLE_TO_FETCH_PERFORMANCE`, `DNS_FAILED`, `DOMAIN_ALREADY_EXISTS`, `NO_CUSTOM_DOMAIN`, `PURGE_CACHE_FAILED`, `LOGS_UNAVAILABLE`, `METRICS_NOT_SUPPORTED`
  </Accordion>

  <Accordion title="データベースと workspace">
    `DATABASE_CREATION_FAILED`, `DATABASE_UNAVAILABLE`, `RESET_FAILED`, `WORKSPACE_CREATION_FAILED`, `APP_ALREADY_IN_WORKSPACE`, `MEMBER_ALREADY_ADDED`, `CANNOT_EDIT_OWNER`, `CANNOT_INVITE_OWNER`, `CANNOT_LEAVE_OWNER`, `CONFLICTING_RESOURCES`
  </Accordion>

  <Accordion title="プラットフォーム">
    `INTERNAL_SERVER_ERROR`, `CLUSTER_MAINTENANCE_TRY_LATER`, `CLUSTER_SELECTION_FAILED`, `CLUSTER_TIMEOUT`, `CLUSTER_UNAVAILABLE`, `AI_UNAVAILABLE`
  </Accordion>

  <Accordion title="非推奨">
    `CodeRateLimit` (`RATE_LIMIT`) と `CodeRateLimitExceeded` (`RATE_LIMIT_EXCEEDED`) は非推奨としてマークされたうえで、引き続きエクスポートされています。現在の API はどちらの場合も `RATE_LIMITED` (`CodeRateLimited`) を返します。
  </Accordion>
</AccordionGroup>

`AI.Chat` のエラーは、代わりに OpenAI の小文字のコード (`access_denied`、`rate_limit_exceeded`、`server_overloaded` など) を使い、`Code` にはそれがそのまま入ります。[AI](/ja/sdks/go/ai#エラー) を参照してください。

## リトライ

SDK は安全に繰り返せるものだけを、最大 `WithMaxRetries` 回 (デフォルトは `2` なので、最大 3 回の試行) リトライします:

| リトライ対象                     | メソッド                                                   |
| -------------------------- | ------------------------------------------------------ |
| `NETWORK_ERROR`            | `GET` のみ (リアルタイムの接続開始と、レスポンス前の `DownloadSnapshot` を含む) |
| 503 `UPLOAD_BUSY`          | すべてのメソッド                                               |
| 503 `ANALYTICS_BUSY`       | すべてのメソッド                                               |
| 503 `DATABASE_UNAVAILABLE` | `GET` のみ                                               |

次のものは**決して**リトライしません:

* `TIMEOUT`;
* すべての **429**: `RATE_LIMITED` は約 30 分のブロックである可能性があり、`KEEP_CALM` もリトライされません;
* その他の 5xx;
* AI のエラー。

503 `DATABASE_UNAVAILABLE` は変更がすでに適用された後に返されることがあるため、SDK は `GET` 以外ではリトライしません。必要であれば、冪等な変更は自分でリトライしてください。アップロードがリトライされるのは、ボディを再送できる場合だけです。つまり、`*os.File` のようにサイズがわかっている `io.ReaderAt` です ([Commit とアップロード](/ja/sdks/go/commit_and_upload#受け付ける入力)を参照)。

リトライ `n` 回目 (0 から開始) の前の待機時間は `min(8 s, 500 ms · 2^n) · U(0.5, 1)` です。50%〜100% のジッターを伴う指数バックオフです。リトライを無効にするには `WithMaxRetries(0)` を設定します。

## タイムアウト

`WithTimeout` (30 秒) は `ctx` に期限がない場合にのみ適用され、1 つの期限がリトライとバックオフの待機時間を含む呼び出し全体を対象とします。2 分の下限がある呼び出しと、デフォルトの期限がない呼び出しについては、[タイムアウト](/ja/sdks/go/client#タイムアウト)を参照してください。期限を過ぎるとステータス `0` の `TIMEOUT` が返され、リトライされることはなく、`context.DeadlineExceeded` にアンラップされます。

## レート制限

すべてのアカウントには、プランによって決まる 60 秒あたりのリクエスト数の制限があり ([値](/ja/api-reference/limitations-and-restrictions))、一部のルートには独自の制限があります:

* **429 `RATE_LIMITED`**: アカウント、API キー、または IP のブロックで、約 30 分続くことがあります。ネットワーク系 endpoint と `Account.Snapshots` の制限でもあります。
* **429 `KEEP_CALM`**: 短時間に 1 つのルートへの呼び出しが多すぎる。

SDK は 429 を決してリトライしません。ペースを落とし、しばらく待ってから再試行してください。
