On Error
Registers a per-island error handler. The runtime routes uncaught errors through a central sink: local .onError() handlers first (in declaration order), then the app-wide onUncaughtError() sink if the island has none, then console.error so nothing is swallowed silently.
Island errors that reach the sink include:
.on()— sync throws and async rejections (except filteredAbortError).effect()— sync throws from the effect body or its cleanup.onMount()— throws from the mount callback or its returned cleanup.transition()— throws or rejections fromenter/leave
Derived failures are not reported here — they surface on derived.key.error. Malformed hydration snapshots degrade gracefully and are not routed to .onError().
Basic usage
Catching async rejections
.onError() also catches rejections from async .on() handlers:
import const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha from "ilha";
const const Form: Island<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>>Form = const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.state<boolean, "loading">(key: "loading", init?: StateInit<Record<string, unknown>, boolean> | undefined): IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>, Record<never, never>>state("loading", false)
.IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>, Record<never, never>>.on<"form@submit">(selectorOrCombined: "form@submit", handler: (ctx: HandlerContextFor<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>, "submit", Record<never, never>>) => void | Promise<void>): IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>, Record<never, never>>on("form@submit", async ({ state: IslandState<MergeState<Record<never, never>, "loading", boolean>>state, event: SubmitEventevent, signal: AbortSignalAbortSignal that fires when the island unmounts. If the handler's selector
was registered with the `:abortable` modifier, the signal is also aborted
when the same listener fires again on the same target.signal }) => {
event: SubmitEventevent.Event.preventDefault(): voidThe **`preventDefault()`** method of the Event interface tells the user agent that the event is being explicitly handled, so its default action, such as page scrolling, link navigation, or pasting text, should not be taken.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/preventDefault)preventDefault();
state: IslandState<MergeState<Record<never, never>, "loading", boolean>>state.loading: MarkedSignalAccessor
(value: boolean) => void (+1 overload)
loading(true);
const const res: Responseres = await function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)fetch("/api/submit", {
RequestInit.method?: string | undefinedA string to set request's method.method: "POST",
RequestInit.signal?: AbortSignal | null | undefinedAn AbortSignal to set request's signal.signal,
});
if (!const res: Responseres.Response.ok: booleanThe **`ok`** read-only property of the Response interface contains a Boolean stating whether the response was successful (status in the range 200-299) or not.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/ok)ok) throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("Submit failed");
state: IslandState<MergeState<Record<never, never>, "loading", boolean>>state.loading: MarkedSignalAccessor
(value: boolean) => void (+1 overload)
loading(false);
})
.IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>, Record<never, never>>.onError(fn: (ctx: ErrorContext<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>, Record<never, never>>) => void): IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>, Record<never, never>>onError(({ error: Errorerror }) => {
function alert(message?: any): void**`window.alert()`** instructs the browser to display a dialog with an optional message, and to wait until the user dismisses the dialog.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/alert)alert(error: Errorerror.Error.message: stringmessage);
})
.IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>, Record<never, never>>.render(fn: (ctx: RenderContext<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>, Record<never, never>>) => string | RawHtml): Island<Record<string, unknown>, MergeState<Record<never, never>, "loading", boolean>>render(({ state: IslandState<MergeState<Record<never, never>, "loading", boolean>>state }) => (
<IntrinsicElements[string]: anyform>
<IntrinsicElements[string]: anybutton type: stringtype="submit" disabled: booleandisabled={state: IslandState<MergeState<Record<never, never>, "loading", boolean>>state.loading: MarkedSignalAccessor
() => boolean (+1 overload)
loading()}>
{state: IslandState<MergeState<Record<never, never>, "loading", boolean>>state.loading: MarkedSignalAccessor
() => boolean (+1 overload)
loading() ? "Submitting…" : "Submit"}
</IntrinsicElements[string]: anybutton>
</IntrinsicElements[string]: anyform>
));
Error context
The handler receives an ErrorContext:
{
error: Error; // always wrapped to Error if a non-Error was thrown
source: "on" | "effect" | "mount" | "transition";
state: IslandState; // reactive state signals
derived: IslandDerived; // current derived values
input: TInput; // resolved input props
host: Element; // island root element
}
Use source to branch logging or UX:
import const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha from "ilha";
const const Island: Island<Record<string, unknown>, Record<never, never>>Island = const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.on<"button@click">(selectorOrCombined: "button@click", handler: (ctx: HandlerContextFor<Record<string, unknown>, Record<never, never>, "click", Record<never, never>>) => void | Promise<void>): IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>on("button@click", () => {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("click failed");
})
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.onError(fn: (ctx: ErrorContext<Record<string, unknown>, Record<never, never>, Record<never, never>>) => void): IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>onError(({ error: Errorerror, source: ErrorSourcesource }) => {
const const label: "Handler" | "Effect" | "Mount" | "Transition"label =
source: ErrorSourcesource === "on"
? "Handler"
: source: "effect" | "mount" | "transition"source === "effect"
? "Effect"
: source: "mount" | "transition"source === "mount"
? "Mount"
: "Transition";
var console: Consoleconsole.Console.error(...data: any[]): voidThe **`console.error()`** static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static)error(`${const label: "Handler" | "Effect" | "Mount" | "Transition"label}:`, error: Errorerror);
})
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.render(fn: (ctx: RenderContext<Record<string, unknown>, Record<never, never>, Record<never, never>>) => string | RawHtml): Island<Record<string, unknown>, Record<never, never>>render(() => <IntrinsicElements[string]: anybutton>Go</IntrinsicElements[string]: anybutton>);
Global error sink — onUncaughtError()
Import onUncaughtError from ilha (not chained on the builder). Register it once in your client entry — for example logging, toast, or telemetry — for any island that has no local .onError():
import ilha, { onUncaughtError } from "ilha";
const off = onUncaughtError((error, source) => {
console.error(`[ilha:${source}]`, error);
});
// later: off() stops delivery
The callback receives (error, source) only — not full ErrorContext (state, host, etc.). Use per-island .onError() when you need that context.
Behavior Detail Precedence Islands with .onError() handle errors locally; the global sink is not called for those errors. Fallback order No local handlers → global sink(s) → console.error if no global handler is registered. Multiple globals Each onUncaughtError() registration runs; a throw inside one global handler is logged and does not stop the others. Unsubscribe The returned function removes that handler from the global set.
import const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha, { function onUncaughtError(fn: (error: Error, source: ErrorSource) => void): () => voidRegister a global error handler invoked when any island reports an error
(from .on, .effect, .onMount, or transitions) and has no local .onError()
handler. Returns an unsubscribe function. Islands with their own .onError()
are handled locally and do not reach the global sink.onUncaughtError } from "ilha";
function onUncaughtError(fn: (error: Error, source: ErrorSource) => void): () => voidRegister a global error handler invoked when any island reports an error
(from .on, .effect, .onMount, or transitions) and has no local .onError()
handler. Returns an unsubscribe function. Islands with their own .onError()
are handled locally and do not reach the global sink.onUncaughtError((error: Errorerror, source: ErrorSourcesource) => {
if (source: ErrorSourcesource === "on") var console: Consoleconsole.Console.error(...data: any[]): voidThe **`console.error()`** static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static)error("[click]", error: Errorerror);
});
// This island has no .onError() — clicks reach the global sink.
const const Loose: Island<Record<string, unknown>, Record<never, never>>Loose = const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.on<"button@click">(selectorOrCombined: "button@click", handler: (ctx: HandlerContextFor<Record<string, unknown>, Record<never, never>, "click", Record<never, never>>) => void | Promise<void>): IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>on("button@click", () => {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("oops");
})
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.render(fn: (ctx: RenderContext<Record<string, unknown>, Record<never, never>, Record<never, never>>) => string | RawHtml): Island<Record<string, unknown>, Record<never, never>>render(() => <IntrinsicElements[string]: anybutton>Go</IntrinsicElements[string]: anybutton>);
Multiple error handlers
Chain .onError() as many times as needed. All handlers run in declaration order. An error thrown inside one .onError() handler does not break the others — it is logged to console.error and execution continues:
import const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha from "ilha";
const const Island: Island<Record<string, unknown>, Record<never, never>>Island = const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.on<"button@click">(selectorOrCombined: "button@click", handler: (ctx: HandlerContextFor<Record<string, unknown>, Record<never, never>, "click", Record<never, never>>) => void | Promise<void>): IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>on("button@click", () => {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("boom");
})
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.onError(fn: (ctx: ErrorContext<Record<string, unknown>, Record<never, never>, Record<never, never>>) => void): IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>onError(({ error: Errorerror }) => {
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("first handler", error: Errorerror.Error.message: stringmessage);
})
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.onError(fn: (ctx: ErrorContext<Record<string, unknown>, Record<never, never>, Record<never, never>>) => void): IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>onError(({ error: Errorerror }) => {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("handler itself failed");
})
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.onError(fn: (ctx: ErrorContext<Record<string, unknown>, Record<never, never>, Record<never, never>>) => void): IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>onError(({ error: Errorerror }) => {
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("third handler still runs", error: Errorerror.Error.message: stringmessage);
})
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.render(fn: (ctx: RenderContext<Record<string, unknown>, Record<never, never>, Record<never, never>>) => string | RawHtml): Island<Record<string, unknown>, Record<never, never>>render(() => <IntrinsicElements[string]: anybutton>Go</IntrinsicElements[string]: anybutton>);
AbortError is not an error
AbortError rejections from .on() handlers are not routed to .onError(). They are the expected outcome of cancellation (via :abortable race-cancel or unmount) and would otherwise pollute error tracking:
import const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha from "ilha";
const const Search: Island<Record<string, unknown>, MergeState<Record<never, never>, "query", string>>Search = const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.state<string, "query">(key: "query", init?: StateInit<Record<string, unknown>, string> | undefined): IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "query", string>, Record<never, never>>state("query", "")
.IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "query", string>, Record<never, never>>.on<"input@input:abortable">(selectorOrCombined: "input@input:abortable", handler: (ctx: HandlerContextFor<Record<string, unknown>, MergeState<Record<never, never>, "query", string>, "input", Record<never, never>>) => void | Promise<void>): IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "query", string>, Record<never, never>>on("input@input:abortable", async ({ event: InputEventevent, signal: AbortSignalAbortSignal that fires when the island unmounts. If the handler's selector
was registered with the `:abortable` modifier, the signal is also aborted
when the same listener fires again on the same target.signal }) => {
const const q: stringq = (event: InputEventevent.Event.target: EventTarget | nullThe read-only **`target`** property of the Event interface is a reference to the object onto which the event was dispatched. It is different from Event.currentTarget when the event handler is called during the bubbling or capturing phase of the event.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/target)target as HTMLInputElement).HTMLInputElement.value: stringThe **`value`** property of the HTMLInputElement interface represents the current value of the <input> element as a string.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/value)value;
await function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)fetch(`/search?q=${const q: stringq}`, { RequestInit.signal?: AbortSignal | null | undefinedAn AbortSignal to set request's signal.signal });
})
.IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "query", string>, Record<never, never>>.onError(fn: (ctx: ErrorContext<Record<string, unknown>, MergeState<Record<never, never>, "query", string>, Record<never, never>>) => void): IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "query", string>, Record<never, never>>onError(({ error: Errorerror }) => {
// This is NOT called for AbortError rejections.
var console: Consoleconsole.Console.error(...data: any[]): voidThe **`console.error()`** static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static)error(error: Errorerror);
})
.IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "query", string>, Record<never, never>>.render(fn: (ctx: RenderContext<Record<string, unknown>, MergeState<Record<never, never>, "query", string>, Record<never, never>>) => string | RawHtml): Island<Record<string, unknown>, MergeState<Record<never, never>, "query", string>>render(() => <IntrinsicElements[string]: anyinput />);
Catching effect errors
.onError() catches synchronous throws from .effect() runs. The runtime does not await async work spawned inside an effect, so passing signal to fetch only cancels the request — it does not prevent unhandled rejections. You must await the promise (if the effect callback is async) or attach .catch() inside the effect itself, and handle AbortError there. Do not rely on .onError() to catch rejected promises from async work inside .effect():
import const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha from "ilha";
const const Island: Island<Record<string, unknown>, MergeState<Record<never, never>, "count", number>>Island = const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.state<number, "count">(key: "count", init?: StateInit<Record<string, unknown>, number> | undefined): IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "count", number>, Record<never, never>>state("count", 0)
.IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "count", number>, Record<never, never>>.effect(fn: (ctx: EffectContext<Record<string, unknown>, MergeState<Record<never, never>, "count", number>, Record<never, never>>) => (() => void) | void): IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "count", number>, Record<never, never>>effect(({ state: IslandState<MergeState<Record<never, never>, "count", number>>state }) => {
if (state: IslandState<MergeState<Record<never, never>, "count", number>>state.count: MarkedSignalAccessor
() => number (+1 overload)
count() < 0) {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("count cannot be negative");
}
})
.IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "count", number>, Record<never, never>>.onError(fn: (ctx: ErrorContext<Record<string, unknown>, MergeState<Record<never, never>, "count", number>, Record<never, never>>) => void): IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "count", number>, Record<never, never>>onError(({ error: Errorerror, source: ErrorSourcesource }) => {
var console: Consoleconsole.Console.error(...data: any[]): voidThe **`console.error()`** static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static)error(`[${source: ErrorSourcesource}] ${error: Errorerror.Error.message: stringmessage}`);
})
.IlhaBuilder<Record<string, unknown>, MergeState<Record<never, never>, "count", number>, Record<never, never>>.render(fn: (ctx: RenderContext<Record<string, unknown>, MergeState<Record<never, never>, "count", number>, Record<never, never>>) => string | RawHtml): Island<Record<string, unknown>, MergeState<Record<never, never>, "count", number>>render(({ state: IslandState<MergeState<Record<never, never>, "count", number>>state }) => <IntrinsicElements[string]: anyp>{state: IslandState<MergeState<Record<never, never>, "count", number>>state.count: MarkedSignalAccessor
() => number (+1 overload)
count()}</IntrinsicElements[string]: anyp>);
Notes
- Fallback order: local
.onError() → onUncaughtError() → console.error.
AbortError rejections from cancelled .on() work are always filtered out (not errors).
- Errors thrown inside
.onError() or global handlers are logged but do not break other handlers in the same tier.
.onError() and onUncaughtError() run client-side only — not during SSR.
- Rejected promises from fire-and-forget async work inside
.effect() are not awaited by the runtime; handle them inside the effect (.catch() / await), not via .onError().