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

[Question] The need for second parameter passed to fromPromise #586

Open
jansedlon opened this issue Sep 25, 2024 · 3 comments
Open

[Question] The need for second parameter passed to fromPromise #586

jansedlon opened this issue Sep 25, 2024 · 3 comments

Comments

@jansedlon
Copy link

Hello,

Sorry for creating an issue but there are no discussions.

My question is why is passing errorFn mandatory? In 99% of cases i just type e => e because there's no need to create my own error. What are your use cases for creating custom errors? When im doing a function call to a database, passing e => new Error("Creating something failed", {cause: e} ) seems redundant.

Any explanation is greatly appreciated.

@paduc
Copy link
Contributor

paduc commented Sep 25, 2024

Hello @jansedlon

fromPromise acts as an interface between value-typed world Promise<V> to the value- and error-typed world ResultAsync<V,E>. It is there that you should provide the error types ‘E.

if you use ‘e => e’ as an errorFn you get a ‘ResultAsync<V, any>’ which kinda wastes neverthrow’s purpose.

sorry for the typos, mobile

@jansedlon
Copy link
Author

Hello @paduc , thank you for your explanation. Am I correct that in 99% of cases what is thrown is an instance of Error? So why not change the default error type to Error and make errorFn optional?

Do you have any examples of yours? For example when talking to a DB, etc.

I know I could just make a wrapper myself but I'm just wondering about this.

@paduc
Copy link
Contributor

paduc commented Sep 26, 2024

@jansedlon I don't think 99% of cases are of type Error quite the contrary.

Here's an example taken from the prisma documentation:

import { PrismaClient, Prisma } from '@prisma/client'

const client = new PrismaClient()

try {
  await client.user.create({ data: { email: '[email protected]' } })
} catch (e) {
  if (e instanceof Prisma.PrismaClientKnownRequestError) {
    // The .code property can be accessed in a type-safe manner
    if (e.code === 'P2002') {
      console.log(
        'There is a unique constraint violation, a new user cannot be created with this email'
      )
    }
  }
  throw e
}

Here is what you would do with neverthrow

import { PrismaClient, Prisma } from '@prisma/client'

class UserAlreadyExistsError extends Error {}
class DatabaseError extends Error {}

const client = new PrismaClient()

const userCreationPromise = client.user.create({ data: { email: '[email protected]' } })

const userCreationResult = Result.fromPromise(userCreationPromise, (e) => {
   if (e instanceof Prisma.PrismaClientKnownRequestError) {
    if (e.code === 'P2002') {
      return new UserAlreadyExistsError()
    }
  }
  return new DatabaseError()
})
// ResultAsync<boolean, UserAlreadyExistsError | DatabaseError>

It helps isolate the different error cases for our own domain. We do not want prisma specific errors which might become irrelevant when we change ORMs.

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

2 participants