Skip to content

Conversation

@GiantRobots
Copy link
Collaborator

Description & motivation 💭

Screenshots (if applicable) 📸

Design Considerations 🎨

Testing 🧪

How was this tested 👻

  • Manual testing
  • E2E tests added
  • Unit tests added

Steps for others to test: 🚶🏽‍♂️🚶🏽‍♀️

Checklists

Draft Checklist

Merge Checklist

Issue(s) closed

Docs

Any docs updates needed?

@vercel
Copy link

vercel bot commented Oct 31, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
holocene Ready Ready Preview Comment Oct 31, 2025 5:29pm

Comment on lines +81 to +83
// but maybe this is leaking information to the users? But it also might be good
// to allow that? Think about this harder maybe ask app sec about if this is an okay
// design choice
Copy link
Collaborator

@Alex-Tideman Alex-Tideman Nov 4, 2025

Choose a reason for hiding this comment

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

We always want to return the original encoded value if decoding fails

{:then decoded}
{@render children(decoded)}
{:catch err}
{@render error?.(() => decodePayloads(value), err)}
Copy link
Collaborator

@Alex-Tideman Alex-Tideman Nov 4, 2025

Choose a reason for hiding this comment

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

This... confuses me?

So you'd pass something like

{#snippet error(retry, err)}
  {#await retry} ...
  {:catch}
   {err}
  {/await}
{/snippet}

Comment on lines +99 to +105
{#await decodeValuePromise}
{@render loading?.(keyedValue)}
{:then decoded}
{@render children(decoded)}
{:catch err}
{@render error?.(() => decodePayloads(value), err)}
{/await}
Copy link
Collaborator

Choose a reason for hiding this comment

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

@claude explain this

Copy link

@claude claude bot Nov 10, 2025

Choose a reason for hiding this comment

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

Claude finished @Alex-Tideman's task —— View job


Explanation of line 105

The code at line 105 (actually the entire block from lines 99-105) is using Svelte 5's {#await} block syntax to handle the asynchronous decoding operation. Here's what's happening:

The Pattern:

{#await decodeValuePromise}
  {@render loading?.(keyedValue)}
{:then decoded}
  {@render children(decoded)}
{:catch err}
  {@render error?.(() => decodePayloads(value), err)}
{/await}

Breaking it down:

  1. Line 99-100 (Pending state): While decodeValuePromise is still loading, it renders the loading snippet, passing the original keyedValue (the stringified unencoded value)

  2. Line 101-102 (Success state): When the promise resolves successfully, it renders the children snippet with the decoded value

  3. Line 103-104 (Error state): If decoding fails, it renders the error snippet with two parameters:

    • First param: A retry function () => decodePayloads(value) - This is an arrow function that, when called, will re-attempt the decode operation
    • Second param: The error object err

Why pass a function instead of calling it?

The key insight is that line 104 passes () => decodePayloads(value) (a function) rather than calling it immediately. This gives control to the error snippet to decide when to retry. The default errorSnip (lines 93-97) calls this function when the user clicks the "Retry Decoding" button:

{#snippet errorSnip(retry, error)}
  <div>{error}</div>
  <Button on:click={retry}>Retry Decoding</Button>
{/snippet}

This pattern allows consumers to provide their own error UI with custom retry behavior while keeping the retry logic (calling decodePayloads) encapsulated in the component.

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.

3 participants