Skip to content

feat: say so when Tangent cannot be reached - #2760

Draft
camielvs wants to merge 1 commit into
09-18-feat_open_a_project_in_tangentfrom
09-18-feat_say_when_tangent_is_unreachable
Draft

camielvs wants to merge 1 commit into
09-18-feat_open_a_project_in_tangentfrom
09-18-feat_say_when_tangent_is_unreachable

Conversation

@camielvs

@camielvs camielvs commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

Now that a project tile and a freshly created project both open a Tangent session, a Tangent that isn't running is something you land on rather than something you have to go looking for. Today that shows a blank page, with only an uncaught rejection in the console to say why.

Tangent isn't reachable
Nothing answered at http://localhost:5173, so this project cannot be opened. Check that Tangent is running and that the workspace points at the right address.
[ Try again ]

Why not an error boundary

The failure is an async rejection, not a render error, so a boundary would never catch it. TangentProvider does:

const [readyPromise] = useState(() => loadEmbedRuntime(url));
useEffect(() => { void readyPromise.then(() => setReady(true)); }, [readyPromise]);

There's no .catch. When the import rejects, ready stays false forever and the provider renders <tangent-provider> with null children — hence the blank page.

How this observes it

loadEmbedRuntime isn't exported from @tangent/embed-react, so useTangentRuntime performs the same dynamic import and watches both outcomes. Module imports are cached per URL by the browser, so this does not fetch twice — the provider's own import resolves against this one.

To remove any chance of the probe and the provider disagreeing about what was tried, the URL is built once and passed to the provider via its existing channelUrl prop (which is documented as defaulting to exactly this path).

A failed module import stays failed for the life of the document, so Try again reloads the page rather than retrying in place.

Scope

TangentProjectPage gains two lines and an early return; the view is its own component so it can be tested — nothing under Tangent/ has component tests, only hooks and services.

Testing

pnpm run validate clean; 2984 tests pass, 6 new.

Verified in a real browser against the dev server with tangent-shell on and no Tangent running: the page now shows the box instead of blank, in both light and dark, and the two uncaught TypeError: Failed to fetch dynamically imported module rejections are gone (the early return means the provider never starts its unhandled import). The ERR_CONNECTION_REFUSED network log remains, as it must.

Not verified: the path where Tangent is reachable — it isn't set up locally. That path is unchanged apart from receiving an explicit channelUrl equal to the default it already computed.

🤖 Generated with Claude Code

@camielvs
camielvs requested a review from a team as a code owner September 18, 2026 22:59
@github-actions

Copy link
Copy Markdown

🎩 Preview

A preview build has been created at: 09-18-feat_say_when_tangent_is_unreachable/fe2475f

camielvs commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@camielvs
camielvs marked this pull request as draft September 19, 2026 00:08
Tangent's UI is a bundle fetched from its own origin at runtime, and the
provider waits on that import without watching for it to fail. A Tangent
that is not running left the page blank for good, with only an uncaught
rejection in the console to say why.

The import is now made here as well, which is what makes the failure
observable — module imports are cached per url, so the provider's own
import resolves against this one rather than fetching twice, and the
same url is handed to the provider so the two cannot disagree about
what was tried.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@camielvs
camielvs force-pushed the 09-18-feat_say_when_tangent_is_unreachable branch from fe2475f to 837e4ed Compare September 23, 2026 20:57
@camielvs
camielvs force-pushed the 09-18-feat_open_a_project_in_tangent branch from 58773a0 to 46de677 Compare September 23, 2026 20:57

This branch has not been deployed

No deployments
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.

1 participant