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

# SDK Python: erros e novas tentativas

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

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

Os exemplos usam o `client` de [Criando o cliente](/pt-br/sdks/py/client#criando-o-cliente). `app_id` é o id de uma das suas aplicações: [`client.account.me()`](/pt-br/sdks/py/client#conta) lista todas.

```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. `RATE_LIMIT` e `RATE_LIMIT_EXCEEDED` continuam listados ali, marcados como depreciados: a API agora responde `RATE_LIMITED` para os dois.

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
```

## Códigos de erro da API

Todos os outros códigos vêm da API. A [referência de erros da API](/pt-br/api-reference/errors) lista cada um com o status HTTP, o significado e a solução, e cada página do SDK lista os códigos que os seus métodos retornam com mais frequência. Qualquer chamada também pode responder 401 `ACCESS_DENIED` (uma chave inválida), 403 `MISSING_SCOPE` ou `RESOURCE_NOT_ALLOWED` (os [limites da chave](/pt-br/sdks/py/client#chave-de-api-e-escopos)), 429 (veja [Rate limits](#rate-limits)) ou 503 `DATABASE_UNAVAILABLE`.

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`**: a conta ou a chave de API ultrapassou a sua cota de requisições e fica bloqueada por cerca de 30 minutos, ou um IP que continua enviando chaves inválidas fica bloqueado por um curto período. 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.

## Próximos passos

<CardGroup cols={2}>
  <Card title="Referência de erros da API" icon="book" href="/pt-br/api-reference/errors">
    Todos os códigos de erro, com o significado e a solução.
  </Card>

  <Card title="Limitações e restrições" icon="gauge" href="/pt-br/api-reference/limitations-and-restrictions">
    Os limites de requisições de cada plano.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.