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

require that promise-returning functions that could throw are async #10809

Open
turadg opened this issue Jan 7, 2025 · 0 comments
Open

require that promise-returning functions that could throw are async #10809

turadg opened this issue Jan 7, 2025 · 0 comments
Labels
devex developer experience enhancement New feature or request

Comments

@turadg
Copy link
Member

turadg commented Jan 7, 2025

What is the Problem Being Solved?

When a sync function returns a Promise, it could throw before the promise is returned. That forces complexity on the caller to handle both exceptions and rejected promises.

Description of the Design

https://typescript-eslint.io/rules/promise-function-async/ is close but has some unnecessary ugliness,

  return E.when(
    E(recoveryPurse).deposit(srcPayment, optAmountShape),
-    amount => E(recoveryPurse).withdraw(amount),
+    async amount => E(recoveryPurse).withdraw(amount),
-  return Promise.all(amounts.map(amount => E(recoveryPurse).withdraw(amount)));
+  return Promise.all(
+   amounts.map(async amount => E(recoveryPurse).withdraw(amount)),
+  );
-  await t.throwsAsync(() => brand.isMyIssuer('not an issuer'), {
+  await t.throwsAsync(async () => brand.isMyIssuer('not an issuer'), {
-export const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
+export const delay = async ms =>
  new Promise(resolve => setTimeout(resolve, ms));
-  return Promise.all(amounts.map(amount => E(recoveryPurse).withdraw(amount)));
+  return Promise.all(
+    amounts.map(async amount => E(recoveryPurse).withdraw(amount)),
+  );

Take their rule and put it into an Agoric eslint plugin (#10665), adding new config options. It should be backwards compatible with typescript-eslint so we can propose adding the features upstream.

A new option like allowBlockless should not flag:

  • a block-less arrow function
  • which only contains expressions that cannot throw
    • calling a promise returning function is assumed to not throw
    • E(foo).bar is known to not throw

We might also need a safePromisNames option to express that EGetters can't throw.

If it's too difficult to generalize for typescript-eslint it could migrate to Endo instead.

Security Considerations

Scaling Considerations

Test Plan

Upgrade Considerations

@turadg turadg added enhancement New feature or request devex developer experience labels Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
devex developer experience enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant