Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
MDX
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970---category: SDKtitle: Error Handlingdescription: "Handle errors and implement retry strategies with the openstatus Node.js SDK"---
The SDK uses ConnectRPC. Errors are thrown as `ConnectError` instances from the `@connectrpc/connect` package.
```typescriptimport { ConnectError } from "@connectrpc/connect";
try { await client.monitor.v1.MonitorService.deleteMonitor({ id: "invalid" });} catch (error) { if (error instanceof ConnectError) { console.error(`Code: ${error.code}`); console.error(`Message: ${error.message}`); }}```
## Common Error Codes
| Code | Description ||------|-------------|| `unauthenticated` | Missing or invalid API key || `not_found` | Resource does not exist || `invalid_argument` | Validation failure (e.g., missing required field, value out of range) || `permission_denied` | No access to this workspace or resource || `already_exists` | Duplicate resource (e.g., slug already taken) || `resource_exhausted` | Rate limited (HTTP `429`); wait for the `Retry-After` header, see [API rate limits](/docs/reference/api-rate-limits) || `unavailable` | The server is shedding load (HTTP `503`); retry with backoff |
## Retry Strategy
ConnectRPC does not retry by default. For transient failures (`resource_exhausted`, `unavailable`, `deadline_exceeded`), implement your own retry logic. The response headers, including `Retry-After`, are available on `error.metadata`; keep the delay at or above that value when it is present:
```typescriptimport { Code, ConnectError } from "@connectrpc/connect";
async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> { for (let attempt = 0; attempt <= maxRetries; attempt++) { try { return await fn(); } catch (error) { if ( error instanceof ConnectError && (error.code === Code.ResourceExhausted || error.code === Code.Unavailable || error.code === Code.DeadlineExceeded) && attempt < maxRetries ) { const retryAfter = Number(error.metadata.get("retry-after")) * 1000; const backoff = 1000 * 2 ** attempt; await new Promise((resolve) => setTimeout(resolve, Math.max(retryAfter || 0, backoff)), ); continue; } throw error; } } throw new Error("Unreachable");}
const { httpMonitors } = await withRetry(() => client.monitor.v1.MonitorService.listMonitors({}));```