> ## 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.

# Erros

> Trate o SquareCloudAPIError no squarecloud-api: status, código e mensagem, os códigos próprios do SDK, os códigos da API por grupo, novas tentativas, timeouts e rate limits.

Toda falha da API e de rede lança uma única exceção: `SquareCloudAPIError`.

```python theme={"system"}
from squarecloud import SquareCloudAPIError

try:
    client.apps.start(app_id)
except SquareCloudAPIError as error:
    print(error.status, error.code, error.message)
    print(error.method, error.path)  # "POST" "/v2/apps/<id>/start"
    print(error)  # POST /v2/apps/<id>/start: HTTP 404 APP_NOT_FOUND
```

## `SquareCloudAPIError`

`SquareCloudAPIError` é uma subclasse de `Exception`.

| Atributo  | Tipo                    | Descrição                                                                                     |
| --------- | ----------------------- | --------------------------------------------------------------------------------------------- |
| `status`  | `int`                   | Status HTTP. `0` quando nenhuma resposta chegou (erro de rede, timeout, verificação local)    |
| `code`    | `str`                   | O código de erro da API, por exemplo `APP_NOT_FOUND`, ou um dos códigos do SDK                |
| `message` | `str`                   | A explicação do servidor. `''` quando o servidor enviou apenas um código                      |
| `method`  | `str`                   | Método HTTP da chamada que falhou                                                             |
| `path`    | `str`                   | Caminho da URL da chamada que falhou, sem a query string                                      |
| `cause`   | `BaseException \| None` | A exceção original, para `NETWORK_ERROR`, `TIMEOUT` e JSON inválido (a mesma que `__cause__`) |

`str(error)` é `<METHOD> <path>: HTTP <status> <CODE>: <message>`, sem `HTTP <status>` quando o status é `0` e sem `: <message>` quando a mensagem está vazia.

Duas falhas não são encapsuladas:

* Uma chave de API vazia ou composta apenas de espaços lança um `ValueError` no construtor do cliente.
* Problemas com arquivos locais lançam um `OSError`: um caminho de upload que não pode ser aberto, um arquivo que se torna ilegível no meio do upload, ou um destino de `download_snapshot` em que não é possível escrever.

## Códigos do SDK

| Status   | Código           | Quando                                                                                                                                                                                                                                  |
| -------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 0        | `NETWORK_ERROR`  | Sem resposta (DNS, conexão reiniciada, corpo cortado). A exceção original está em `cause`                                                                                                                                               |
| 0        | `TIMEOUT`        | Uma operação de socket excedeu o [timeout](/pt-br/sdks/py/client#timeouts)                                                                                                                                                              |
| 0        | `FILE_TOO_LARGE` | Verificação local: um upload acima de 100 MB ou um `files.write` acima de 10 MB. Nada foi enviado                                                                                                                                       |
| 0        | `INVALID_ID`     | Verificação local: um id vazio, `.` ou `..`. Nada foi enviado                                                                                                                                                                           |
| qualquer | `UNKNOWN_ERROR`  | Uma resposta sem código (como uma página de erro de proxy), com o `status` real e a mensagem do servidor, ou `HTTP <status>` quando não há nenhuma. Um corpo 2xx que não é JSON tem a mensagem `Invalid JSON in HTTP <status> response` |

## Códigos são strings

`code` é uma `str` simples: o SDK não tem um enum de códigos. A docstring de `SquareCloudAPIError` lista todos os códigos conhecidos da API, e os grupos abaixo também os listam.

A lista de códigos da API cresce. **Trate um código desconhecido pelo seu status HTTP**:

```python theme={"system"}
def start(app_id: str):
    try:
        client.apps.start(app_id)
    except SquareCloudAPIError as error:
        match error.code:
            case "APP_NOT_FOUND":
                return None
            case "CONTAINER_ALREADY_STARTED":
                return  # fine
            case _:
                if error.status == 429:
                    return retry_later()
                if error.status >= 500:
                    return report_outage(error)
                raise
```

## Erros de qualquer chamada

| Status | Código                  | Quando                                                                                                                 |
| ------ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 401    | `ACCESS_DENIED`         | Chave de API ausente, desconhecida, revogada ou expirada                                                               |
| 403    | `MISSING_SCOPE`         | A chave não tem o escopo desta chamada. `message` o informa                                                            |
| 403    | `RESOURCE_NOT_ALLOWED`  | A chave está limitada a outras aplicações ou bancos de dados                                                           |
| 403    | `PERMISSION_DENIED`     | Seu cargo no workspace não permite a ação                                                                              |
| 404    | `ROUTE_NOT_FOUND`       | Rota desconhecida                                                                                                      |
| 429    | `RATE_LIMITED`          | Bloqueio de conta, chave ou IP (pode durar cerca de 30 min), e o limite dos endpoints de rede e de `account.snapshots` |
| 429    | `KEEP_CALM`             | Rápido demais para esta rota                                                                                           |
| 500    | `INTERNAL_SERVER_ERROR` | Erro no servidor                                                                                                       |
| 503    | `DATABASE_UNAVAILABLE`  | O banco de dados da plataforma está indisponível. Uma mutação pode já ter sido aplicada                                |

## Códigos da API por grupo

<AccordionGroup>
  <Accordion title="Não encontrado">
    `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="Validação">
    `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="Autenticação e permissões">
    `ACCESS_DENIED`, `MISSING_SCOPE`, `RESOURCE_NOT_ALLOWED`, `PERMISSION_DENIED`, `SCOPE_NOT_GRANTABLE`, `BLOCKED_PATH`, `UPGRADE_REQUIRED`
  </Accordion>

  <Accordion title="Limites e rate limits">
    `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="Containers (start, stop, restart)">
    `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="Uploads, arquivos e commits">
    `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="Snapshots">
    `SNAPSHOT_FAILED`, `SNAPSHOT_PROCESSING`, `SNAPSHOT_RESTORE_FAILED`, `SNAPSHOT_DATABASE_MISMATCH`, `RESTORE_IN_PROGRESS`
  </Accordion>

  <Accordion title="Deploys e 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="Rede e domínios">
    `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="Bancos de dados e workspaces">
    `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="Plataforma">
    `INTERNAL_SERVER_ERROR`, `CLUSTER_MAINTENANCE_TRY_LATER`, `CLUSTER_SELECTION_FAILED`, `CLUSTER_TIMEOUT`, `CLUSTER_UNAVAILABLE`, `AI_UNAVAILABLE`
  </Accordion>

  <Accordion title="Depreciados">
    `RATE_LIMIT` e `RATE_LIMIT_EXCEEDED` ainda estão listados, marcados como depreciados: a API agora responde `RATE_LIMITED` para ambos.
  </Accordion>
</AccordionGroup>

Os erros de `ai.chat()` usam, em vez disso, códigos da OpenAI em minúsculas (`access_denied`, `rate_limit_exceeded`, `server_overloaded`, ...). Veja [IA](/pt-br/sdks/py/ai#erros).

## Novas tentativas

O SDK só tenta novamente o que é seguro repetir, até `max_retries` vezes (padrão `2`, ou seja, até 3 tentativas):

| Repetido                   | Métodos         |
| -------------------------- | --------------- |
| `NETWORK_ERROR`            | Apenas `GET`    |
| 503 `UPLOAD_BUSY`          | Qualquer método |
| 503 `ANALYTICS_BUSY`       | Qualquer método |
| 503 `DATABASE_UNAVAILABLE` | Apenas `GET`    |

Ele **nunca** tenta novamente:

* `TIMEOUT`;
* qualquer **429**: `RATE_LIMITED` pode ser um bloqueio de cerca de 30 minutos, e `KEEP_CALM` também não é repetido;
* outros 5xx;
* erros de IA.

O 503 `DATABASE_UNAVAILABLE` pode chegar depois que uma mutação já foi aplicada, então o SDK não o repete fora de `GET`. Repita suas próprias mutações idempotentes se precisar.

A espera antes da nova tentativa `n` (começando em 0) é `min(8 s, 500 ms · 2^n) · U(0.5, 1)`: backoff exponencial com jitter de 50% a 100%. Defina `max_retries=0` para desativar as novas tentativas.

## Timeouts

`timeout` (30 s) se aplica **por operação de socket** (a conexão e cada leitura ou escrita), não à requisição inteira. Veja [Timeouts](/pt-br/sdks/py/client#timeouts) para as chamadas com mínimo de 120 s e as chamadas sem timeout. Um timeout lança `TIMEOUT` com status `0` e nunca é repetido.

## Rate limits

Toda conta tem um limite de requisições a cada 60 segundos, definido pelo seu plano ([valores](/pt-br/api-reference/limitations-and-restrictions)), e algumas rotas têm limites próprios:

* **429 `RATE_LIMITED`**: um bloqueio da conta, da chave de API ou do IP, que pode durar cerca de 30 minutos. Também é o limite dos endpoints de rede e de `account.snapshots`.
* **429 `KEEP_CALM`**: chamadas demais a uma rota em pouco tempo.

O SDK nunca repete um 429. Diminua o ritmo e aguarde antes de tentar novamente.
