Skip to content

Errors

asimo provides two error classes for structured error handling.

AsimoError

Thrown for runtime errors — primarily “service not found” and circular bundle detection.

import { AsimoError } from "@asimojs/asimo";

“Service not found” is caught at compile time when types are used properly. With IIDs declared in dependencies and no any casts, TypeScript surfaces missing services as ServiceDependencyNotRegistered compile errors. A runtime AsimoError for “Service not found” only occurs when types are bypassed (e.g., Container<any>, any-typed IID tokens, or getOptional/fetchOptional without a fallback).

Constructor

new AsimoError(message: string, container: string)
ParameterTypeDescription
messagestringError description (without prefix or path).
containerstringThe container path where the error occurred.

Properties

PropertyTypeDescription
messagestringFull error message: "[Asimo] {message} at {container}"
namestringAlways "AsimoError"
containerstringThe container path where the error occurred.
messagePrefixstringAlways "[Asimo] "

Example

try {
await container.fetch(FLAKY_SVC);
} catch (err) {
if (err instanceof AsimoError) {
// Structural error — circular bundle, invalid name, etc.
console.log(err.container); // "/app"
}
if (err instanceof AsimoLoadError) {
// Load failed after retries — err.cause has the original error
}
}

Common Messages

ScenarioMessage
Service not found"Service not found: {ns}"
Circular bundle"Circular bundle loading detected for: {ns}"
Invalid container name"Container name must not contain forward slashes"
Corrupt service entry"Corrupt service entry in serviceMap"
Missing brand symbol"is not assignable to type 'ServiceDependencyNotRegistered<...>'"

AsimoLoadError

import { AsimoLoadError } from "@asimojs/asimo";

A subclass of AsimoError thrown when a service or bundle load fails after exhausting all retry attempts.

Constructor

new AsimoLoadError(message: string, container: string, cause?: unknown)
ParameterTypeDescription
messagestringError description with attempt count.
containerstringThe container path.
causeunknownThe original error that caused the load failure.

Properties

PropertyTypeDescription
messagestringFull error message with retry count: "[Asimo] Load failed for \"{ns}\" after {n} attempts at {path}"
namestringAlways "AsimoLoadError"
containerstringThe container path.
causeunknownThe original thrown value from the factory/bundle load() call.
messagePrefixstringAlways "[Asimo] " (inherited from AsimoError).

Example

try {
await container.fetch(FLAKY_SVC);
} catch (err) {
if (err instanceof AsimoLoadError) {
// err.message = "[Asimo] Load failed for \"app.FlakySvc\" after 4 attempts at /app"
// err.container = "/app"
// err.cause = Error("something went wrong") — the original error
// err.name = "AsimoLoadError"
}
}

Error Hierarchy

Error
└── AsimoError
├── message: "[Asimo] {msg} at {container}"
├── container: string
├── name: "AsimoError"
└── AsimoLoadError
├── cause: unknown
└── name: "AsimoLoadError"

Using onError Hook

Instead of try/catch around every resolution, use config.onError for centralized error handling:

const app = createContainer({
name: "app",
config: {
onError(error, container) {
// All AsimoError instances flow through here
console.error(`${error.name} in ${container.path}: ${error.message}`);
if (error instanceof AsimoLoadError && error.cause) {
console.error("Caused by:", error.cause);
}
},
},
services: [...],
});