From 2edee3188e4b7a57ffd830d2db3dfd131605be57 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 11 Feb 2026 13:25:02 -0500 Subject: [PATCH] onerror -> handleError --- packages/svelte/src/index.d.ts | 4 +-- .../internal/client/dom/blocks/boundary.js | 26 ++++++++--------- packages/svelte/src/internal/client/render.js | 11 +++++--- packages/svelte/src/internal/server/index.js | 2 +- .../svelte/src/internal/server/renderer.js | 28 +++++++++---------- packages/svelte/src/server/index.d.ts | 4 +-- .../svelte/tests/runtime-legacy/shared.ts | 6 ++-- .../samples/async-error-boundary/_config.js | 2 +- .../samples/error-boundary-26/_config.js | 2 +- .../_config.js | 4 +-- .../boundary-error-no-onerror/_config.js | 2 +- .../boundary-error-with-onerror/_config.js | 6 ++-- .../tests/server-side-rendering/test.ts | 4 +-- packages/svelte/types/index.d.ts | 12 ++++---- 14 files changed, 58 insertions(+), 55 deletions(-) diff --git a/packages/svelte/src/index.d.ts b/packages/svelte/src/index.d.ts index 2eeaecf550..f3ff534162 100644 --- a/packages/svelte/src/index.d.ts +++ b/packages/svelte/src/index.d.ts @@ -340,9 +340,9 @@ export type MountOptions = Record intro?: boolean; /** * A function that transforms errors caught by error boundaries before they are passed to the `failed` snippet. - * This is used by SvelteKit to apply `handleError`. Defaults to the identity function on the client, and to throwing on the server. + * Defaults to the identity function. */ - onerror?: (error: unknown) => unknown | Promise; + handleError?: (error: unknown) => unknown | Promise; } & ({} extends Props ? { /** diff --git a/packages/svelte/src/internal/client/dom/blocks/boundary.js b/packages/svelte/src/internal/client/dom/blocks/boundary.js index d862addf51..7e8c0713c3 100644 --- a/packages/svelte/src/internal/client/dom/blocks/boundary.js +++ b/packages/svelte/src/internal/client/dom/blocks/boundary.js @@ -59,11 +59,11 @@ var flags = EFFECT_TRANSPARENT | EFFECT_PRESERVED | BOUNDARY_EFFECT; * @param {TemplateNode} node * @param {BoundaryProps} props * @param {((anchor: Node) => void)} children - * @param {((error: unknown) => unknown) | undefined} [onerror_transform] + * @param {((error: unknown) => unknown) | undefined} [transform_error] * @returns {void} */ -export function boundary(node, props, children, onerror_transform) { - new Boundary(node, props, children, onerror_transform); +export function boundary(node, props, children, transform_error) { + new Boundary(node, props, children, transform_error); } export class Boundary { @@ -73,11 +73,11 @@ export class Boundary { is_pending = false; /** - * API-level onerror transform function. Transforms errors before they reach the `failed` snippet. + * API-level handleError transform function. Transforms errors before they reach the `failed` snippet. * Inherited from parent boundary, or defaults to identity. * @type {(error: unknown) => unknown} */ - onerror_transform; + transform_error; /** @type {TemplateNode} */ #anchor; @@ -146,18 +146,18 @@ export class Boundary { * @param {TemplateNode} node * @param {BoundaryProps} props * @param {((anchor: Node) => void)} children - * @param {((error: unknown) => unknown) | undefined} [onerror_transform] + * @param {((error: unknown) => unknown) | undefined} [transform_error] */ - constructor(node, props, children, onerror_transform) { + constructor(node, props, children, transform_error) { this.#anchor = node; this.#props = props; this.#children = children; this.parent = /** @type {Effect} */ (active_effect).b; - // Inherit onerror_transform from parent boundary, or use the provided one, or default to identity - this.onerror_transform = - onerror_transform ?? (this.parent ? this.parent.onerror_transform : (e) => e); + // Inherit transform_error from parent boundary, or use the provided one, or default to identity + this.transform_error = + transform_error ?? (this.parent ? this.parent.transform_error : (e) => e); this.is_pending = !!this.#props.pending; @@ -522,11 +522,11 @@ export class Boundary { }; queue_micro_task(() => { - // Run the error through the API-level onerror transform (e.g. SvelteKit's handleError) + // Run the error through the API-level handleError transform (e.g. SvelteKit's handleError) /** @type {unknown} */ var result; try { - result = this.onerror_transform(error); + result = this.transform_error(error); } catch (e) { invoke_error_boundary(e, this.#effect && this.#effect.parent); return; @@ -537,7 +537,7 @@ export class Boundary { typeof result === 'object' && typeof (/** @type {any} */ (result).then) === 'function' ) { - // onerror returned a Promise — wait for it + // handleError returned a Promise — wait for it /** @type {any} */ (result).then( /** @param {unknown} transformed_error */ (transformed_error) => handle_error_result(transformed_error), diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index 143e5309c9..6894e5fab5 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -81,7 +81,7 @@ export function mount(component, options) { * context?: Map; * intro?: boolean; * recover?: boolean; - * onerror?: (error: unknown) => unknown; + * handleError?: (error: unknown) => unknown; * } : { * target: Document | Element | ShadowRoot; * props: Props; @@ -89,7 +89,7 @@ export function mount(component, options) { * context?: Map; * intro?: boolean; * recover?: boolean; - * onerror?: (error: unknown) => unknown; + * handleError?: (error: unknown) => unknown; * }} options * @returns {Exports} */ @@ -160,7 +160,10 @@ const document_listeners = new Map(); * @param {MountOptions} options * @returns {Exports} */ -function _mount(Component, { target, anchor, props = {}, events, context, intro = true, onerror }) { +function _mount( + Component, + { target, anchor, props = {}, events, context, intro = true, handleError } +) { init_operations(); /** @type {Set} */ @@ -243,7 +246,7 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro pop(); }, - onerror + handleError ); return () => { diff --git a/packages/svelte/src/internal/server/index.js b/packages/svelte/src/internal/server/index.js index 3d1163df17..730ebb3250 100644 --- a/packages/svelte/src/internal/server/index.js +++ b/packages/svelte/src/internal/server/index.js @@ -56,7 +56,7 @@ export function element(renderer, tag, attributes_fn = noop, children_fn = noop) * Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app. * @template {Record} Props * @param {Component | ComponentType>} component - * @param {{ props?: Omit; context?: Map; idPrefix?: string; csp?: Csp; onerror?: (error: unknown) => unknown }} [options] + * @param {{ props?: Omit; context?: Map; idPrefix?: string; csp?: Csp; handleError?: (error: unknown) => unknown }} [options] * @returns {RenderOutput} */ export function render(component, options = {}) { diff --git a/packages/svelte/src/internal/server/renderer.js b/packages/svelte/src/internal/server/renderer.js index 05be58060a..e527e6483e 100644 --- a/packages/svelte/src/internal/server/renderer.js +++ b/packages/svelte/src/internal/server/renderer.js @@ -52,7 +52,7 @@ export class Renderer { /** * If set, this renderer is an error boundary. When async collection * of the children fails, the failed snippet is rendered instead. - * @type {{ failed: (renderer: Renderer, error: unknown, reset: () => void) => void; onerror: (error: unknown) => unknown } | null} + * @type {{ failed: (renderer: Renderer, error: unknown, reset: () => void) => void; handleError: (error: unknown) => unknown } | null} */ #boundary = null; @@ -224,7 +224,7 @@ export class Renderer { /** * Render children inside an error boundary. If the children throw and the API-level - * `onerror` transform handles the error (doesn't re-throw), the `failed` snippet is + * `handleError` transform handles the error (doesn't re-throw), the `failed` snippet is * rendered instead. Otherwise the error propagates. * * @param {{ failed?: (renderer: Renderer, error: unknown, reset: () => void) => void }} props @@ -240,7 +240,7 @@ export class Renderer { if (props.failed) { child.#boundary = { failed: props.failed, - onerror: this.global.onerror + handleError: this.global.handleError }; } @@ -273,7 +273,7 @@ export class Renderer { if (!failed_snippet) throw error; - const result = this.global.onerror(error); + const result = this.global.handleError(error); if (result instanceof Promise) { if (this.global.mode === 'sync') { @@ -684,9 +684,9 @@ export class Renderer { content.head += boundary_content.head; content.body += boundary_content.body; } catch (error) { - const { failed, onerror } = item.#boundary; + const { failed, handleError } = item.#boundary; - let transformed = await onerror(error); + let transformed = await handleError(error); // Render the failed snippet instead of the partial children content const failed_renderer = new Renderer(item.global, item); @@ -728,7 +728,7 @@ export class Renderer { * @template {Record} Props * @param {'sync' | 'async'} mode * @param {import('svelte').Component} component - * @param {{ props?: Omit; context?: Map; idPrefix?: string; csp?: Csp; onerror?: (error: unknown) => unknown }} options + * @param {{ props?: Omit; context?: Map; idPrefix?: string; csp?: Csp; handleError?: (error: unknown) => unknown }} options * @returns {Renderer} */ static #open_render(mode, component, options) { @@ -737,7 +737,7 @@ export class Renderer { mode, options.idPrefix ? options.idPrefix + '-' : '', options.csp, - options.onerror + options.handleError ) ); @@ -851,11 +851,11 @@ export class SSRState { css = new Set(); /** - * `onerror` transform passed to `render`. Called when an error boundary catches an error. + * `handleError` transform passed to `render`. Called when an error boundary catches an error. * Throws by default if unset in `render`. * @type {(error: unknown) => unknown} */ - onerror; + handleError; /** @type {{ path: number[], value: string }} */ #title = { path: [], value: '' }; @@ -864,14 +864,14 @@ export class SSRState { * @param {'sync' | 'async'} mode * @param {string} id_prefix * @param {Csp} csp - * @param {((error: unknown) => unknown) | undefined} [onerror] + * @param {((error: unknown) => unknown) | undefined} [handleError] */ - constructor(mode, id_prefix = '', csp = { hash: false }, onerror) { + constructor(mode, id_prefix = '', csp = { hash: false }, handleError) { this.mode = mode; this.csp = { ...csp, script_hashes: [] }; - this.onerror = - onerror ?? + this.handleError = + handleError ?? ((error) => { throw error; }); diff --git a/packages/svelte/src/server/index.d.ts b/packages/svelte/src/server/index.d.ts index 34e0a539bf..214549c2bb 100644 --- a/packages/svelte/src/server/index.d.ts +++ b/packages/svelte/src/server/index.d.ts @@ -17,7 +17,7 @@ export function render< context?: Map; idPrefix?: string; csp?: Csp; - onerror?: (error: unknown) => unknown | Promise; + handleError?: (error: unknown) => unknown | Promise; } ] : [ @@ -27,7 +27,7 @@ export function render< context?: Map; idPrefix?: string; csp?: Csp; - onerror?: (error: unknown) => unknown | Promise; + handleError?: (error: unknown) => unknown | Promise; } ] ): RenderOutput; diff --git a/packages/svelte/tests/runtime-legacy/shared.ts b/packages/svelte/tests/runtime-legacy/shared.ts index 09c5814842..13f42fcdf4 100644 --- a/packages/svelte/tests/runtime-legacy/shared.ts +++ b/packages/svelte/tests/runtime-legacy/shared.ts @@ -101,7 +101,7 @@ export interface RuntimeTest = Record unknown; + handleError?: (error: unknown) => unknown; } declare global { @@ -365,7 +365,7 @@ async function run_test_variant( const render_result = render(SsrSvelteComponent, { props: config.server_props ?? config.props ?? {}, idPrefix: config.id_prefix, - onerror: config.onerror + handleError: config.handleError }); const rendered = variant === 'async-ssr' || (variant === 'hydrate' && compileOptions.experimental?.async) @@ -465,7 +465,7 @@ async function run_test_variant( props, intro: config.intro, recover: config.recover ?? false, - onerror: config.onerror + handleError: config.handleError }); } } else { diff --git a/packages/svelte/tests/runtime-runes/samples/async-error-boundary/_config.js b/packages/svelte/tests/runtime-runes/samples/async-error-boundary/_config.js index 68708ed38e..72de1960f3 100644 --- a/packages/svelte/tests/runtime-runes/samples/async-error-boundary/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/async-error-boundary/_config.js @@ -4,7 +4,7 @@ import { test } from '../../test'; export default test({ mode: ['hydrate', 'async-server', 'client'], ssrHtml: '

caught: error

', - onerror: (error) => { + handleError: (error) => { if (error !== 'catch me') throw 'wrong error object'; return 'error'; }, diff --git a/packages/svelte/tests/runtime-runes/samples/error-boundary-26/_config.js b/packages/svelte/tests/runtime-runes/samples/error-boundary-26/_config.js index 68708ed38e..72de1960f3 100644 --- a/packages/svelte/tests/runtime-runes/samples/error-boundary-26/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/error-boundary-26/_config.js @@ -4,7 +4,7 @@ import { test } from '../../test'; export default test({ mode: ['hydrate', 'async-server', 'client'], ssrHtml: '

caught: error

', - onerror: (error) => { + handleError: (error) => { if (error !== 'catch me') throw 'wrong error object'; return 'error'; }, diff --git a/packages/svelte/tests/server-side-rendering/samples/boundary-error-no-failed-snippet/_config.js b/packages/svelte/tests/server-side-rendering/samples/boundary-error-no-failed-snippet/_config.js index 7fa380ec92..c04b527f8e 100644 --- a/packages/svelte/tests/server-side-rendering/samples/boundary-error-no-failed-snippet/_config.js +++ b/packages/svelte/tests/server-side-rendering/samples/boundary-error-no-failed-snippet/_config.js @@ -1,8 +1,8 @@ import { test } from '../../test'; export default test({ - // onerror handles the error, but there's no failed snippet. + // handleError handles the error, but there's no failed snippet. // The error should still propagate because there's nothing to render instead. - onerror: () => 'you will not see me', + handleError: () => 'you will not see me', error: 'component error' }); diff --git a/packages/svelte/tests/server-side-rendering/samples/boundary-error-no-onerror/_config.js b/packages/svelte/tests/server-side-rendering/samples/boundary-error-no-onerror/_config.js index 44ed740b80..6e9b5381a8 100644 --- a/packages/svelte/tests/server-side-rendering/samples/boundary-error-no-onerror/_config.js +++ b/packages/svelte/tests/server-side-rendering/samples/boundary-error-no-onerror/_config.js @@ -1,6 +1,6 @@ import { test } from '../../test'; export default test({ - // No onerror - by default the server throws, so the error should propagate. + // No handleError - by default the server throws, so the error should propagate. error: 'component error' }); diff --git a/packages/svelte/tests/server-side-rendering/samples/boundary-error-with-onerror/_config.js b/packages/svelte/tests/server-side-rendering/samples/boundary-error-with-onerror/_config.js index a9986b1183..d88cfb14ca 100644 --- a/packages/svelte/tests/server-side-rendering/samples/boundary-error-with-onerror/_config.js +++ b/packages/svelte/tests/server-side-rendering/samples/boundary-error-with-onerror/_config.js @@ -1,10 +1,10 @@ import { test } from '../../test'; export default test({ - // boundary with failed snippet exists, so onerror should transform the error - onerror: (error) => { + // boundary with failed snippet exists, so handleError should transform the error + handleError: (error) => { if (/** @type {Error} */ (error).message !== 'you are not supposed to see this message') { - return 'wrong object passed to onerror'; + return 'wrong object passed to handleError'; } return 'component error'; } diff --git a/packages/svelte/tests/server-side-rendering/test.ts b/packages/svelte/tests/server-side-rendering/test.ts index 78bb35b28c..53a120d565 100644 --- a/packages/svelte/tests/server-side-rendering/test.ts +++ b/packages/svelte/tests/server-side-rendering/test.ts @@ -24,7 +24,7 @@ interface SSRTest extends BaseTest { error?: string; csp?: { nonce: string } | { hash: true }; script_hashes?: string[]; - onerror?: (error: unknown) => unknown; + handleError?: (error: unknown) => unknown; } // TODO remove this shim when we can @@ -86,7 +86,7 @@ const { test, run } = suite_with_variants unknown | Promise; + handleError?: (error: unknown) => unknown | Promise; } & ({} extends Props ? { /** @@ -547,7 +547,7 @@ declare module 'svelte' { context?: Map; intro?: boolean; recover?: boolean; - onerror: (error: unknown) => unknown; + handleError?: (error: unknown) => unknown; } : { target: Document | Element | ShadowRoot; props: Props; @@ -555,7 +555,7 @@ declare module 'svelte' { context?: Map; intro?: boolean; recover?: boolean; - onerror?: (error: unknown) => unknown; + handleError?: (error: unknown) => unknown; }): Exports; /** * Unmounts a component that was previously mounted using `mount` or `hydrate`. @@ -2567,7 +2567,7 @@ declare module 'svelte/server' { context?: Map; idPrefix?: string; csp?: Csp; - onerror?: (error: unknown) => unknown | Promise; + handleError?: (error: unknown) => unknown | Promise; } ] : [ @@ -2577,7 +2577,7 @@ declare module 'svelte/server' { context?: Map; idPrefix?: string; csp?: Csp; - onerror?: (error: unknown) => unknown | Promise; + handleError?: (error: unknown) => unknown | Promise; } ] ): RenderOutput;