Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make userSeat.getPayout(foo) throw if foo is not present #10738

Merged
merged 5 commits into from
Jan 3, 2025

Conversation

Chris-Hibbert
Copy link
Contributor

@Chris-Hibbert Chris-Hibbert commented Dec 18, 2024

closes: #8610

Description

#8610 explains that getPayout(foo) returns undefined, which doesn't match the declarations. I explored changing the types to indicate that undefined is possible, but that would have required that many tests override the types.

It seems cleaner to change the implementation to throw if the named key doesn't correspond to a payment. Callers shouldn't make that mistake outside of tests. If they're uncertain they should call getPayouts() instead.

Security Considerations

No impact

Scaling Considerations

Not relevant

Documentation Considerations

I update the declaration in types-ambient.js, so the generated docs will be updated automatically. I'll create a separate PR to update github.com/Agoric/documentation.

Testing Considerations

Added a test that shows the throw. Nothing else was impacted.

Upgrade Considerations

No relevance.

@Chris-Hibbert Chris-Hibbert added Zoe package: Zoe hygiene Tidying up around the house labels Dec 18, 2024
@Chris-Hibbert Chris-Hibbert self-assigned this Dec 18, 2024
@Chris-Hibbert Chris-Hibbert requested a review from a team as a code owner December 18, 2024 20:51
Copy link

cloudflare-workers-and-pages bot commented Jan 3, 2025

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: 64b3b38
Status: ✅  Deploy successful!
Preview URL: https://a5327a97.agoric-sdk.pages.dev
Branch Preview URL: https://8610-getpayout-type.agoric-sdk.pages.dev

View logs

@Chris-Hibbert Chris-Hibbert changed the title chore: correct declaration of userSeat.getPayout(); cascade fixes make userSeat.getPayout(foo) throw if foo is not present Jan 3, 2025
Copy link
Member

@turadg turadg left a comment

Choose a reason for hiding this comment

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

Design change LGTM but I'd want to hear from @erights too

@@ -143,8 +148,8 @@ export const makeZoeSeatAdminFactory = baggage => {
// doExit(), which ensures that finalPayouts() has set state.payouts.
return E.when(
state.subscriber.subscribeAfter(),
() => state.payouts[keyword],
() => state.payouts[keyword],
() => getPayoutOrThrow(state, keyword),
Copy link
Member

Choose a reason for hiding this comment

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

Please use NonNullish() instead of a new function

Copy link
Member

Choose a reason for hiding this comment

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

When switching to NonNullish, please remember to use the second optional optDetails argument so the error message remains informative.

Copy link
Member

@erights erights left a comment

Choose a reason for hiding this comment

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

LGTM. Yes, as a general principle we should prefer errors rather than nullish for failures that most likely indicate that there's a bug somewhere that needs to be fixed.

@@ -143,8 +148,8 @@ export const makeZoeSeatAdminFactory = baggage => {
// doExit(), which ensures that finalPayouts() has set state.payouts.
return E.when(
state.subscriber.subscribeAfter(),
() => state.payouts[keyword],
() => state.payouts[keyword],
() => getPayoutOrThrow(state, keyword),
Copy link
Member

Choose a reason for hiding this comment

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

When switching to NonNullish, please remember to use the second optional optDetails argument so the error message remains informative.

@erights
Copy link
Member

erights commented Jan 3, 2025

#8610 explains that getPayout(foo) returns null,

Please correct this PR comment before merging.

I looked, and #8610 correctly explains that it returned undefined for that case. Please always be careful about the distinctions between null, undefined, nullish (null or undefined), and falsy. The manual test you're currently doing here

state.payouts[keyword] || Fail`No payout for ${keyword}`;

(that NonNullish will replace) is testing for falsy. NonNullish, as its name correctly implies, tests for nullish. As does the new ?? operator, introduced as an alternative to || for precisely this reason.

'' || 3; // 3
'' ?? 3; // ''

Yes, it sucks that JS forces all these usually-pointless distinctions on us. But given that it does, we need to avoid any further muddying of these treacherous waters.

@mergify mergify bot merged commit 103e0bc into master Jan 3, 2025
81 checks passed
@mergify mergify bot deleted the 8610-getPayout-type branch January 3, 2025 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:squash Automatically squash merge hygiene Tidying up around the house Zoe package: Zoe
Projects
None yet
Development

Successfully merging this pull request may close these issues.

E(userSeat).getPayout('NoSuchKeyword') result violates documented types
3 participants