Errors PRO
When something goes wrong, the status code says what kind of problem it is, and the body explains it:
json
{
"error": {
"code": "NOT_FOUND",
"message": "Product not found.",
"request_id": "req_ftth2xt814314w"
}
}| Field | What it's for |
|---|---|
code | Stable and made for code. It never changes, so write your if against this. |
message | For people, in English. It can get better over time, so don't compare it. |
retry_after | Only on 429: how many seconds to wait. |
request_id | Send it to support if something looks wrong. |
All the codes
| Status | code | What happened | What to do |
|---|---|---|---|
| 400 | BAD_REQUEST | Something in the request is wrong. The message says what. | Fix the request. Trying again won't help. |
| 401 | UNAUTHORIZED | No key, a wrong key, or a revoked key. | Check the Authorization header. |
| 403 | MISSING_SCOPE | The key isn't allowed to do this. | Add the scope in Store settings → API. |
| 403 | PRO_REQUIRED | The store has no Pro, or it expired (for changes). | Renew Pro. Reading keeps working when it expired. |
| 403 | STORE_SUSPENDED | The store is suspended: read-only. | Contact support. |
| 404 | NOT_FOUND | That route or thing doesn't exist in this store. | Check the id. |
| 409 | CONFLICT | It clashes with the current state, like redelivering a refunded sale. | Read the message. Trying again won't help. |
| 409 | IDEMPOTENCY_MISMATCH | The same Idempotency-Key came with a different body. | Use a new key for a new action. |
| 429 | RATE_LIMITED | A limit was reached. | Wait retry_after seconds. See Limits. |
| 500 | INTERNAL | Our fault. | Try again. If it keeps happening, send the request_id to support. |
Examples
A wrong value names the field:
json
{
"error": {
"code": "BAD_REQUEST",
"message": "body.price: Too small: expected number to be >=0",
"request_id": "req_vz899gn85hnvdb"
}
}So does a field the route doesn't know, which usually means a typo:
json
{
"error": {
"code": "BAD_REQUEST",
"message": "body: Unrecognized key: \"color\"; body: send at least one field",
"request_id": "req_yvnwhzcph0spxs"
}
}Handling errors
Two questions cover almost everything: should I try again? and should a person look at this?
js
async function fasty(path, options = {}) {
const res = await fetch(`https://api.fastyvendor.com/api/v1${path}`, {
...options,
headers: { Authorization: `Bearer ${process.env.FASTY_KEY}`, ...options.headers },
})
const data = await res.json()
if (res.ok) return data
const { code, message, request_id } = data.error
throw Object.assign(new Error(`${code}: ${message} (${request_id})`), { code, status: res.status })
}
try {
const product = await fasty('/products/prd_nothing')
} catch (e) {
if (e.code === 'NOT_FOUND') console.log('No such product')
else throw e
}python
import os, requests
class FastyError(Exception):
def __init__(self, status, error):
super().__init__(f"{error['code']}: {error['message']} ({error['request_id']})")
self.status, self.code = status, error["code"]
def fasty(method, path, **kwargs):
res = requests.request(
method,
f"https://api.fastyvendor.com/api/v1{path}",
headers={"Authorization": f"Bearer {os.environ['FASTY_KEY']}"},
**kwargs,
)
data = res.json()
if res.ok:
return data
raise FastyError(res.status_code, data["error"])
try:
product = fasty("GET", "/products/prd_nothing")
except FastyError as e:
if e.code == "NOT_FOUND":
print("No such product")
else:
raiselsl
http_response(key id, integer status, list meta, string body)
{
if (status == 200 || status == 201) return; // all good: read the body here
string code = llJsonGetValue(body, ["error", "code"]);
if (code == "RATE_LIMITED")
llSetTimerEvent((float)llJsonGetValue(body, ["error", "retry_after"]));
else
llOwnerSay("Fasty: " + llJsonGetValue(body, ["error", "message"]));
}Timeouts are not errors
If the connection drops, you don't know if Fasty got your request. Retry with the same Idempotency-Key and nothing happens twice.