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

Wrap async/sync result in the library #111

Open
keogami opened this issue Nov 21, 2022 · 4 comments
Open

Wrap async/sync result in the library #111

keogami opened this issue Nov 21, 2022 · 4 comments

Comments

@keogami
Copy link

keogami commented Nov 21, 2022

Its super common for async/sync operations to throw an error, but i don't see a constructor to conveniently wrap the operation in the Result. I propose a new constructor:

async function AsyncResultOf<T>(val: Promise<T>): Promise<Result<T, Error>> {
  try {
    return Ok(await val);
  } catch(err) {
    return Err(err);
  }
}

This allows us to go from the throw/catch error handling to the monadic error handling patterns const result = await AsyncResultOf(fetch(...))

I will go further to suggest an even more general constructor that translates both async and non-async fallible operations:

async function ResultOf<T>(val: () => Promise<T>): Promise<Result<T, Error>> {
  try {
    return Ok(await val());
  } catch(err) {
    return Err(err);
  }
}

This can of course be overloaded with the signature of AsyncResultOf.

(PS im trying to whip up a PR but the test keeps saying "Timed out while running tests" on my machine)

@keogami
Copy link
Author

keogami commented Nov 22, 2022

image
i changed results.ts interestingly.

@cawabunga
Copy link

cawabunga commented Jan 19, 2023

I think your proposal is interesting. Have you considered using TaskEither from the fp-ts library? It could be more suitable for more complex scenarios. Additionally, if we're planning to support this constructor, we should also consider adding a wrapper for regular functions. Your syntax seems fitting for this purpose:

function resultOf<T, E = unknown>(val: () => T): Result<T, E> {
  try {
    return Ok(val());
  } catch(err) {
    return Err(err);
  }
}

// usage:
const result = resultOf(() => 10 / 0);

Also, I have modified the error type, as we cannot be certain that the thrown value is an error.

upd: I hadn't seen your PR #112 , when I sent the comment.

@keogami
Copy link
Author

keogami commented Jan 19, 2023

My bad, I should have linked this issue with my PR.

fp-ts's TaskEither is a good analog. However, Either is a more generalized form of Result as in Result makes it explicit that you will either get the result or the error.

And from non-async functions i meant regular functions, yes.

@danawoodman
Copy link

Would be cool to see this implemented :)

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

No branches or pull requests

3 participants