Errors
Every failure in @cstar.help/js throws a CStarError subclass. Catch by class
— strings rotate; class identity doesn't. Every error carries a request ID; paste it into a support
ticket and we find the call in seconds.
Catch by class
Match on the typed subclass and recover differently per case. instanceof works
across every subpath import — /auth, /library, /community, /quickhelp, /proactive — because the class
identity is registered on a Symbol.for(...) slot of globalThis. Bundle
splits don't break the check.
import {
CStarError,
CStarValidationError,
CStarRateLimitError,
CStarAuthenticationError
} from '@cstar.help/js';
try {
await cstar.tickets.create(formData);
} catch (e) {
if (e instanceof CStarValidationError) {
// e.param holds the offending field name
return showFieldError(e.param, e.message);
}
if (e instanceof CStarRateLimitError) {
return retryAfter(e.retryAfter); // seconds, default 60
}
if (e instanceof CStarAuthenticationError) {
// Bad/expired key. Bounce the user to settings.
return redirectToKeyRotation();
}
if (e instanceof CStarError) {
// Catch-all for any other typed cStar error.
log.error('cStar call failed', {
code: e.code,
requestId: e.requestId,
docUrl: e.docUrl,
statusCode: e.statusCode
});
}
throw e;
}Every error carries
The base class fields land on every subclass. Most of what you need to file a support ticket is already there.
The subclasses
Eight typed subclasses, dispatched by HTTP status and error type.
CStarAuthenticationError 401 Missing or invalid API key. Bad Authorization header.
CStarPermissionError 403 Wrong key type for the operation, or your role lacks the permission.
CStarNotFoundError 404 The resource ID doesn't exist (or your key can't see it).
CStarValidationError 400 / 422 Bad payload. e.param holds the field name.
CStarConflictError 409 Idempotency replay or unique-key conflict.
CStarRateLimitError 429 e.retryAfter tells you how many seconds to wait (default 60).
CStarServerError 5xx Our problem. Retry once with backoff; ping support with the request ID if it persists.
CStarFeatureNotConfiguredError 409 The team hasn't enabled the feature this call needs (e.g. AI). e.feature + e.enableUrl tell you where to go.
Request IDs
Every error carries requestId. So does every successful response, via cstar.lastMeta.requestId. Both pull from the same source — the x-cstar-request-id header that every cStar response emits.
try {
const ticket = await cstar.tickets.create(payload);
log.info('ticket created', {
ticketId: ticket.id,
requestId: cstar.lastMeta.requestId
});
} catch (e) {
// Always log the request ID. Always.
log.error('ticket.create failed', {
code: e.code,
requestId: e.requestId,
docUrl: e.docUrl
});
throw e;
}Cross-subpath identity
The error classes live on globalThis[Symbol.for('@cstar.help/js/errors/v1')]. That
means an error thrown by LibraryClient (imported from @cstar.help/js/library) and caught with CStarError imported from the
root entry — different bundles, different module copies — still resolves to the same class
identity at runtime. instanceof works across every subpath.
Each subpath also re-exports the canonical error classes for ergonomics, so you can import { CStarError } from '@cstar.help/js/library' if you prefer.