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 filtered AbortError)
  • .effect() — sync throws from the effect body or its cleanup
  • .onMount() — throws from the mount callback or its returned cleanup
  • .transition() — throws or rejections from enter / 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: AbortSignal
AbortSignal 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(): void
The **`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 | undefined
A string to set request's method.
method
: "POST",
RequestInit.signal?: AbortSignal | null | undefined
An AbortSignal to set request's signal.
signal
,
}); if (!const res: Responseres.Response.ok: boolean
The **`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[]): void
The **`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.

BehaviorDetail
PrecedenceIslands with .onError() handle errors locally; the global sink is not called for those errors.
Fallback orderNo local handlers → global sink(s) → console.error if no global handler is registered.
Multiple globalsEach onUncaughtError() registration runs; a throw inside one global handler is logged and does not stop the others.
UnsubscribeThe 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): () => void
Register 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): () => void
Register 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[]): void
The **`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[]): void
The **`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[]): void
The **`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: AbortSignal
AbortSignal 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 | null
The 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: string
The **`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 | undefined
An 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[]): void
The **`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[]): void
The **`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().