Skip to content

feat: allow error boundaries to work on the server#17672

Merged
Rich-Harris merged 21 commits intomainfrom
ssr-error-boundary
Feb 18, 2026
Merged

feat: allow error boundaries to work on the server#17672
Rich-Harris merged 21 commits intomainfrom
ssr-error-boundary

Conversation

@dummdidumm
Copy link
Member

This makes error boundaries run on the server if a new onerror handler is passed to render. onerror can either synchronously or asynchronously return a value. It should be a sanitized JSON.stringify-able value so that it can be passed to the client for hydration via a comment. mount/hydrate also get the onerror property.

If no onerror is passed to render it will just throw just like before, hence this is backwards compatible.

This work is important for SvelteKit to allow +error.svelte to make use of them and in general to make boundaries properly work during SSR (also see sveltejs/kit#14398).

closes #15370

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.
  • If this PR changes code within packages/svelte/src, add a changeset (npx changeset).

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

This makes error boundaries run on the server if a new `onerror` handler is passed to `render`. `onerror` can either synchronously or asynchronously return a value. It should be a sanitized JSON.stringify-able value so that it can be passed to the client for hydration via a comment. `mount/hydrate` also get the `onerror` property.

If no `onerror` is passed to `render` it will just throw just like before, hence this is backwards compatible.

This work is important for SvelteKit to allow `+error.svelte` to make use of them and in general to make boundaries properly work during SSR (also see sveltejs/kit#14398).

closes #15370
@changeset-bot
Copy link

changeset-bot bot commented Feb 10, 2026

🦋 Changeset detected

Latest commit: 584d271

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@dummdidumm dummdidumm temporarily deployed to Publish pkg.pr.new (maintainers) February 10, 2026 22:24 — with GitHub Actions Inactive
@svelte-docs-bot
Copy link

@github-actions
Copy link
Contributor

Playground

pnpm add https://pkg.pr.new/svelte@17672

@dummdidumm dummdidumm temporarily deployed to Publish pkg.pr.new (maintainers) February 10, 2026 22:35 — with GitHub Actions Inactive
@Rich-Harris
Copy link
Member

I wonder if we should call the app-level onerror handleError instead, to a) differentiate it from the boundary-level handler and b) align it with SvelteKit's handleError?

@dummdidumm
Copy link
Member Author

Marking as draft, want to see if this really does what it should in combination with SvelteKit

@dummdidumm dummdidumm marked this pull request as draft February 10, 2026 23:25
@Rich-Harris
Copy link
Member

If a failed snippet is SSR'd, should the boundary's onerror be called with the serialized error upon hydration? My gut says yes

@Rich-Harris
Copy link
Member

this was too cumbersome to do with the suggestion UI: #17673

@dummdidumm dummdidumm temporarily deployed to Publish pkg.pr.new (maintainers) February 11, 2026 09:42 — with GitHub Actions Inactive
@dummdidumm dummdidumm temporarily deployed to Publish pkg.pr.new (maintainers) February 11, 2026 10:27 — with GitHub Actions Inactive
@Rich-Harris Rich-Harris temporarily deployed to Publish pkg.pr.new (maintainers) February 11, 2026 18:27 — with GitHub Actions Inactive
@Rich-Harris Rich-Harris temporarily deployed to Publish pkg.pr.new (maintainers) February 11, 2026 19:10 — with GitHub Actions Inactive
@Rich-Harris Rich-Harris temporarily deployed to Publish pkg.pr.new (maintainers) February 11, 2026 19:35 — with GitHub Actions Inactive
@Rich-Harris Rich-Harris temporarily deployed to Publish pkg.pr.new (maintainers) February 11, 2026 19:41 — with GitHub Actions Inactive
@Rich-Harris Rich-Harris temporarily deployed to Publish pkg.pr.new (maintainers) February 11, 2026 19:55 — with GitHub Actions Inactive
@Rich-Harris Rich-Harris temporarily deployed to Publish pkg.pr.new (maintainers) February 11, 2026 20:20 — with GitHub Actions Inactive
Copy link
Member

@Rich-Harris Rich-Harris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the caveat that we should try this out in SvelteKit to make sure we haven't missed anything obvious, this looks excellent

@dummdidumm dummdidumm temporarily deployed to Publish pkg.pr.new (maintainers) February 11, 2026 21:20 — with GitHub Actions Inactive
@dummdidumm dummdidumm temporarily deployed to Publish pkg.pr.new (maintainers) February 11, 2026 21:47 — with GitHub Actions Inactive
@Rich-Harris
Copy link
Member

Recapping offline discussion: it would be much better if transformError could be synchronous. This would have the knock-on effect of forcing handleError in SvelteKit to be synchronous, which would be a breaking change. Personally I think it's a change that makes sense; if we require handleError to be sync during the flagged-in period we can at least flush out any valid use cases for returning a promise

@Rich-Harris
Copy link
Member

Counterpoint: sveltejs/kit#7756

dummdidumm added a commit to sveltejs/kit that referenced this pull request Feb 12, 2026
Take advantage of sveltejs/svelte#17672 to add the `handleError` hook as `transformError` so that error boundaries run on the server. Behind an experimental flag.

Closes #14808
Closes #14410
Closes #14398
@Rich-Harris Rich-Harris marked this pull request as ready for review February 18, 2026 21:50
@Rich-Harris Rich-Harris merged commit 2661513 into main Feb 18, 2026
20 checks passed
@Rich-Harris Rich-Harris deleted the ssr-error-boundary branch February 18, 2026 21:50
@github-actions github-actions bot mentioned this pull request Feb 18, 2026
Rich-Harris pushed a commit that referenced this pull request Feb 18, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## svelte@5.53.0

### Minor Changes

- feat: allow comments in tags
([#17671](#17671))

- feat: allow error boundaries to work on the server
([#17672](#17672))

### Patch Changes

- fix: use TrustedHTML to test for customizable <select> support, where
necessary ([#17743](#17743))

- fix: ensure head effects are kept in the effect tree
([#17746](#17746))

- chore: deactivate current_batch by default in unset_context
([#17738](#17738))

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: <svelte:boundary> is not working on SSR

2 participants