Errors, timeouts and retries
How to read what `invoke` returns when something goes wrong, and when you can safely call again.
1. The error object
invoke returns { data, error } and never throws. error is an AuraError, so isAuraError(error) is true. Two subclasses tell you who failed:
| Field | Meaning |
|---|---|
error.status | HTTP status. 0 means the failure happened on the client (no response). |
error.code | Stable identifier, for example NOT_FOUND, QUOTA_EXCEEDED, timeout, invalid_body. |
error.message | The text your function returned, or the platform's explanation. |
error.context | On a FunctionsHttpError: the body your function returned (parsed JSON or text). |
error.details | The raw error body. For a platform error it contains error.request_id. |
2. Which error is it?
Behaviours observed against a running stack. The quota row follows the backend's error mapping and was not triggered in our tests.
| What happened | Class | status | code | message |
|---|---|---|---|---|
| The function does not exist | FunctionsHttpError | 404 | NOT_FOUND | "…Fonction 'nope' introuvable" |
Your function returns 500 with text | FunctionsHttpError | 500 | http_500 | that text |
Your function returns 503 itself | FunctionsHttpError | 503 | http_503 | what you returned |
| Your function throws | FunctionsHttpError | 500 | http_500 | "Internal Server Error" |
Your function exceeds its timeout_secs | FunctionsHttpError | 500 or 503 | http_500 / http_503 | "Function execution failed" or "Function returned HTTP 503" |
| The runtime is unreachable | FunctionsRelayError | 503 | SERVICE_UNAVAILABLE | explains that the function was not run |
| The network fails before any response | FunctionsRelayError | 0 | network_error | the network error |
| Plan quota exhausted | FunctionsHttpError | 403 | QUOTA_EXCEEDED | the quota message |
| Too many calls from one client | FunctionsHttpError | 429 | rate_limit_exceeded | wait message |
| Request body too large | FunctionsRelayError | 503 | SERVICE_UNAVAILABLE | "max payload size exceeded" |
You cancelled, or your timeout elapsed | AuraError | 0 | timeout | "Function invocation aborted or timed out" |
| The body cannot be sent as JSON | AuraError | 0 | invalid_body | names the type to avoid |
If your own code returns 502, 503 or 504, you get a FunctionsHttpError: the class tells you who answered, not what the status number is.
A request body above about 256 KiB is rejected with 503 SERVICE_UNAVAILABLE, and a response of about 300 KB or more did not return within our 50-second test. See limits. Retrying does not help; send less data, or use Storage.
3. Decide whether to retry
The SDK never retries an invocation for you: your function may have side effects, and a repeated POST is not safe by default. You decide, using the table below.
| Failure | Did the function run? | Safe to retry? |
|---|---|---|
503 from the platform (FunctionsRelayError) | No, the runtime was unreachable | Yes, with a short back-off |
429 | No | Yes, after the delay in error.retryAfter |
403 QUOTA_EXCEEDED | No | No, until the quota resets or you change plan |
status 0 (network_error) | Unknown | Only if your function is idempotent |
timeout on the client | Unknown | Only if your function is idempotent |
FunctionsHttpError 5xx | Yes, partially or fully | Only if your function is idempotent |
FunctionsHttpError 4xx | Yes | No: fix the request |
The platform does not deduplicate calls and ignores Idempotency-Key. For payments or e-mail, store a key that you pass in body and check it at the start of the function.
4. Timeouts
Three clocks run at once:
| Clock | Default | Where to change it |
|---|---|---|
| Your client | 30 s for every responseType | invoke(…, { timeout }), { signal }, or requestTimeoutMs in the client options |
| The function | 30 s, between 1 and 300 | permissions.timeout_secs on the function |
| The gateway | 380 s | not configurable by projects |
When the function exceeds timeout_secs, the runtime cancels it and your call fails after about that delay, with the 500 or 503 shown above. The cause appears in error.context.detail (WorkerRequestCancelled: request has been cancelled by supervisor) in raw mode. Set your client timeout slightly above the function's timeout_secs to see this error instead of a client timeout.
For work longer than a few seconds, enqueue a job instead of holding a connection open.
5. Find the cause
- Platform errors carry a request id:
error.details.error.request_id. Quote it when you contact support. aura functions logs <name>lists recent HTTP requests with method, path, status, duration and request id. It does not show what your function wrote withconsole.logorconsole.error: that output stays in the runtime's own logs, which only the platform operator can read. See limits for this and the other current gaps.- The identifier of the call is not forwarded to your function. Pass your own id in
headersand log it.