Errors
Every typed error Radon Storage throws, its stable .code string, extra fields, and exactly when it's raised — so you branch on failure kind, never on message text.
Every error Radon throws extends StorageError and carries a stable .code
string. Branch on .code (or instanceof) — never on message text, which can
change.
import { StorageError, ObjectNotFoundError } from "@radonsdk/storage";
try {
await storage.download("missing.png");
} catch (err) {
if (err instanceof ObjectNotFoundError) {
// handle the 404
} else if (err instanceof StorageError) {
console.error(err.code, err.message); // e.g. "provider_error"
}
}Every error
| Error class | .code | Thrown when |
|---|---|---|
StorageError | (varies) | Base class for all of the below — catch it to handle any Radon storage error. |
InvalidConfigError | invalid_config | Bad config caught before any network call: no providers, an unknown defaultProvider/failover slug, a required option missing (R2 accountId, Backblaze region, MinIO/Ceph/IBM/SeaweedFS endpoint, Oracle namespace), or both/neither body/path on a resumable upload. |
ProviderNotFoundError | provider_not_found | A provider slug was requested that isn't registered (built-in or via registerProvider). |
ProviderNotConfiguredError | provider_not_configured | A provider was used that the app never added to its providers config. |
LicenseRequiredError | license_required | A Pro provider — or a Pro feature (resumable upload, failover) — was used without a verified license. Set licenseKey and call await storage.init(). |
LicenseInvalidError | license_invalid | The license key is invalid/revoked, or the license service was unreachable (fail-closed — a network failure during verification also throws this). |
UnsupportedOperationError | unsupported_operation | A provider was asked to do something it genuinely can't — signed URLs on local/Vercel Blob/UploadThing, multipart on a non-multipart provider, copy on a provider with no copy API, a missing credential. |
AuthenticationError | authentication_failed | The provider rejected the credentials — an HTTP 401 or 403 (bad/expired key, wrong region/endpoint). |
ObjectNotFoundError | object_not_found | The requested key doesn't exist — a normalized 404 from download() or getMetadata(). |
ProviderApiError | provider_error | The provider's API returned a non-2xx (rejected request, 5xx) that isn't an auth failure or a 404. |
NetworkError | network_error | A transport failure reaching the provider (DNS, timeout, TLS) — the request never got an HTTP response. |
AllProvidersFailedError | all_providers_failed | Every provider in a failover chain failed. |
The full StorageErrorCode union
.code is one of: invalid_config, provider_not_found,
provider_not_configured, license_required, license_invalid,
unsupported_operation, authentication_failed, object_not_found,
upload_failed, provider_error, network_error, all_providers_failed.
Errors that carry extra fields
Several errors attach structured data beyond .code and .message.
UnsupportedOperationError
providerstringoperationstring"signed-url", "copy".if (err instanceof UnsupportedOperationError) {
console.log(`${err.provider} can't ${err.operation}`);
}ObjectNotFoundError
providerstringkeystringAuthenticationError
providerstringProviderApiError
providerstringstatusnumber | undefinedproviderCodestring | undefinedrawunknownNetworkError
providerstringcauseunknownAllProvidersFailedError
errors{ provider: string; error: unknown }[]One entry per attempted provider, in the order they were tried, pairing the slug with the error it threw.
if (err instanceof AllProvidersFailedError) {
for (const { provider, error } of err.errors) {
console.error(`${provider}:`, error);
}
}Common patterns
Treat "missing" as a value, not an error — use exists() instead of catching
ObjectNotFoundError:
if (await storage.exists(key)) {
const bytes = await storage.download(key);
}Check a capability before calling — avoid UnsupportedOperationError
entirely:
const provider = await storage.provider();
if (provider.capabilities.signedUrls) {
await storage.getUrl(key, { signed: true });
}Fail fast at boot — call init() on startup so a bad license or Pro
misconfiguration throws immediately, not on the first request:
await storage.init(); // throws LicenseRequiredError / LicenseInvalidError early