Errors
The two error classes Strapkit throws and how to handle them.
Strapkit splits failures into two error classes so you can handle configuration mistakes differently from runtime problems.
import {
StrapkitConfigError,
StrapkitRuntimeError,
} from '@strapkit/core';StrapkitConfigError
You passed Strapkit something it can't accept — a misspelled option, a
missing apiKey, an out-of-range port. These errors are always the
caller's fault and don't depend on the browser or network.
Thrown when:
| Where | Why |
|---|---|
new Strapkit(opts) | opts isn't a plain object. |
new Strapkit(opts) | An option key is misspelled (suggests apiKey for apikey, etc.). |
new Strapkit(opts) | apiKey is missing or not a non-empty string. |
new Strapkit(opts) | proxyPort isn't an integer between 1 and 65535. |
setApiKey(key) | key isn't a non-empty string. |
error.name is always 'StrapkitConfigError'.
StrapkitRuntimeError
The environment failed Strapkit — the runtime files couldn't load, the proxy rejected the API key, the page isn't running in a browser, etc.
class StrapkitRuntimeError extends Error {
name: 'StrapkitRuntimeError';
cause?: Error; // present when there's an underlying error to forward
}Thrown when:
| Where | Why | cause |
|---|---|---|
new Strapkit(opts) | The page isn't a browser (no WebSocket). | — |
init() | The runtime files couldn't be fetched. | the original error |
init() | The runtime didn't expose the loader Strapkit expected. | — |
init() | The runtime loader threw. | the original error |
init() | The runtime is missing pieces Strapkit relies on. | — |
init() | The proxy rejected the API key (or reported a billing misconfig). | — |
When the proxy rejects the key, Strapkit also replaces the page with a red error banner so the user sees what went wrong even if your app never gets a chance to render.
Proxy connection error codes
When the proxy refuses or terminates a connection for a reason your code should know about, it uses one of these close codes:
| Code | Kind | Meaning |
|---|---|---|
4001 | unauthorized | The API key was rejected. Make sure setApiKey() was called with the right value. |
4007 | metering_misconfigured | The proxy can't track usage — usually a deployment problem on the proxy itself. |
4008 | bad_signature | Bad HMAC signature on a control frame — the session may be compromised or tampered with. |
Other close codes (network blips, generic protocol errors) are treated as transient and Strapkit stays quiet about them.
If you want to react to these in code rather than rely on the error
banner, listen on a WebSocket directly:
const ws = new WebSocket('ws://localhost:8081/');
ws.addEventListener('close', (ev) => {
const info = WebSocket.PROXY_ERROR_CODES?.[ev.code];
if (info?.kind === 'unauthorized') promptUserToReauth();
});The lookup table is exposed on the global WebSocket constructor so
code that doesn't import from @strapkit/core can still recognize the codes.
Recommended pattern
try {
const sk = new Strapkit({ apiKey: KEY });
await sk.init();
} catch (err) {
if (err instanceof StrapkitConfigError) {
// Programming bug — surface to developers, not end users.
showDevError(err);
} else if (err instanceof StrapkitRuntimeError) {
// Environment problem — usually worth showing the user a retry.
if (err.cause) console.error('underlying cause:', err.cause);
showRetryUi(err);
} else {
throw err;
}
}If init() fails, the same error replays on every later call. To retry,
drop the instance and construct a new Strapkit.