Skip to content

Commit 281e28d

Browse files
julianrichieclaude
andcommitted
docs: document error-handling gotchas in README
Clarify that OdxError.code is the JSON-RPC code (not HTTP status), note caller-initiated aborts propagate unwrapped, and that call_method's MissingFnNameError is a rejected promise. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent d92d6a9 commit 281e28d

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,19 +182,21 @@ Each data function also accepts an optional trailing `opts?: OdxRequestOptions`
182182
Every failure is **thrown** as a typed error — proxy-level failures (non-2xx) *and* Odoo logic errors (an `error` body on a `200`). On success the helper resolves to the envelope with `result` set. Use a single `try/catch`:
183183

184184
```ts
185-
import { search_read, AuthError, OdooLogicError, OdxError } from "@terrakernel/odxproxy-client-js";
185+
import { search_read, AuthError, OdooLogicError, OdooTimeoutError, OdxError } from "@terrakernel/odxproxy-client-js";
186186

187187
try {
188188
const res = await search_read("res.partner", [[]], { context: { tz: "UTC" } });
189189
console.log(res.result);
190190
} catch (err) {
191-
if (err instanceof AuthError) { /* bad x-api-key */ }
191+
if (err instanceof AuthError) { /* bad x-api-key — reauth */ }
192192
else if (err instanceof OdooLogicError) { /* Odoo validation/access error */ }
193+
else if (err instanceof OdooTimeoutError) { /* upstream timed out — retry/backoff */ }
193194
else if (err instanceof OdxError) { console.error(err.code, err.message, err.data, err.httpStatus); }
195+
else { throw err; } // not from this SDK (e.g. a caller-initiated AbortError) — propagate
194196
}
195197
```
196198

197-
All errors extend `OdxError` and carry the JSON-RPC `code`, `message`, `data`, and the raw `httpStatus`. Subclasses map to the proxy's error catalog:
199+
All errors extend `OdxError` and carry the JSON-RPC `code`, `message`, `data`, and the raw `httpStatus`. Note that `code` is the **JSON-RPC code** (the values below), *not* the HTTP status — that's on `httpStatus`. Subclasses map to the proxy's error catalog:
198200

199201
| Class | code | When |
200202
|---|---|---|
@@ -207,6 +209,11 @@ All errors extend `OdxError` and carry the JSON-RPC `code`, `message`, `data`, a
207209
| `LicenseError` | 0 | Proxy license expired/invalid (HTTP 403) |
208210
| `OdooLogicError` | *Odoo's code* | Odoo-side logic error returned on a 200 |
209211

212+
Two behaviors worth knowing:
213+
214+
- **Caller-initiated aborts are not wrapped.** If you pass your own `opts.signal` and abort it, the original `AbortError` propagates unchanged — only the client's *own* timeout becomes an `OdooTimeoutError`. So an `instanceof OdxError` branch that re-throws everything else (as above) is the correct shape when you use cancellation.
215+
- **`MissingFnNameError` from `call_method` is a rejected promise, not a synchronous throw.** It's raised client-side before any network call, but via `Promise.reject`, so it's still caught by a `try/catch` around `await` (or a `.catch()`) — just don't expect it to throw before the `await`.
216+
210217
## Auxiliary endpoints
211218

212219
```ts

0 commit comments

Comments
 (0)