prisma: Prisma Client: add `updateOrThrow()` & `deleteOrThrow()`

I think it makes sense to have rejectOnNotFound on update also, and I think it is very weird that it throws an exception instead of returning null.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 45
  • Comments: 24 (1 by maintainers)

Commits related to this issue

Most upvoted comments

+1 for this issue, I think it should return null if record doesnt exist.

example:


const updatedUser = await prisma.user.update({
  where: {
    id: userID
  },
  data: {
    /* some changes */
  }
})

if(!updatedUser) { /* handle if update didnt happen */ }

Up!

Do you plan to develop this feature? I agree that it would makes sense to have it.

For those interested in it, it is still possible to use this workaround which use try/catch:

    async function recoverFromNotFound<A>(
      promise: Promise<A>,
    ): Promise<A | null> {
      try {
        return await promise;
      } catch (e) {
        if (e instanceof Prisma.PrismaClientKnownRequestError) {
          if (e.code === 'P2025') {
            return null;
          }
        }
        throw e;
      }
    }

Here is the usage example based on the @SC0d3r comment:

    const updatedUser = await recoverFromNotFound(
      prisma.user.update({
        where: {
          id: userID,
        },
        data: {
          /* some changes */
        },
      }),
    );

    if (!updatedUser) {
      /* handle if update didn't happen */
    }

Borrowing from @maximeburri but as an extension as an alternative solution:

import { Prisma } from "@prisma/client";

export const IgnoreNotFoundError = Prisma.defineExtension({
    name: 'IgnoreNotFoundError',
    model: {
        $allModels: {
            async updateIgnoreNotFound<T, A>(
                this: T,
                args: Prisma.Exact<A, Prisma.Args<T, 'update'>>
            ): Promise<Prisma.Result<T, A, 'update'> | null> {
                try {
                    const context = Prisma.getExtensionContext(this) as any
                    return await context.update(args)
                } catch (err) {
                    if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === 'P2025') {
                        return null
                    }
                    throw err
                }
            },
            async deleteIgnoreNotFound<T, A>(
                this: T,
                args: Prisma.Exact<A, Prisma.Args<T, 'delete'>>
            ): Promise<Prisma.Result<T, A, 'delete'> | null> {
                try {
                    const context = Prisma.getExtensionContext(this) as any
                    return await context.delete(args)
                } catch (err) {
                    if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === 'P2025') {
                        return null
                    }
                    throw err
                }
            },
        }
    }
})

Usage

    const updatedUser = await prisma.user.updateIgnoreNotFound({
        where: {
          id: userID,
        },
        data: {
          /* some changes */
        },
    });

    if (!updatedUser) {
      /* handle if update didn't happen */
    }

Hi @janpio - I am in agreement with this issue, rejectOnNotFound should support update and delete operations.

Adding a param like this would be a nice addition!

please do not change the default behavior of update because we rely on it for optimistic concurrency control.

if it needed to have some updateOne without throwing error if not found please add some new method.

Hi!

I think also that update should just return null if a record is not found. In my case it would be much more useful since the query is faster when it is ended immediately after record is found and it will not go through all records every time. I think this would be quite important addition. Currently I have a large table in where updating is quite slow due to the fact that I cannot use update in it since it fails on “An operation failed because it depends on one or more records that were required but not found. Record to update not found.” error each time. Instead I am using updateMany and it is quite inefficient.

Issues #5032 is closed as the ugly error was replaced with a more descriptive error: https://github.com/prisma/prisma/issues/5032#issuecomment-786576567 Can you confirm this is still the exception and error you are getting?