Error Message Changing password Implementation

Hi, Here’s my code for an implementation changing a password, (below the error message), I’m using bcrypt.compare()

This is working and the password is being changed, however, I’m getting this error message in the console, I’ve googled but I’d not getting anything re what it’s complaining about, anyone have any ideas?:

Error: No response is returned from route handler 'C:\Users\char5\OneDrive\Web_Projects\2023\next-app\app\api\resetPassword\route.ts'. Ensure you return a `Response` or a `NextResponse` in all branches of your handler.
    at C:\Users\char5\OneDrive\Web_Projects\2023\next-app\node_modules\next\dist\compiled\next-server\app-route.runtime.dev.js:6:61631

here is the route.ts for resetPassword:

import { NextRequest, NextResponse } from 'next/server';
import schema from '../resetPassword/schema';
import prisma from '@/prisma/client';
import bcrypt from 'bcrypt';

export async function PUT(
  request: NextRequest
) {
  const body = await request.json();

  const validation = schema.safeParse(body);
  if (!validation.success)
    return NextResponse.json(validation.error.errors, { status: 400 });

  const user = await prisma.user.findUnique({
    where: { email: body.email },
  });

  if (!user)
    return NextResponse.json({ error: 'User not found' }, { status: 404 });

  const hashedPasswordFromDB = user.hashedPassword;

  const passwordCompare = bcrypt.compare(
    body.oldPassword,
    hashedPasswordFromDB!,
    async function (err, result) {
      if (err)
        return NextResponse.json({ error: err.message }, { status: 500 });
      if (result) {
        console.log('passwords match');

        const newPasswordProvidedAndHashed = await bcrypt.hash(
          body.newPassword,
          10
        );

        const updateUserPassword = await prisma.user.update({
          where: { id: user.id },
          data: {
            email: body.email,
            hashedPassword: newPasswordProvidedAndHashed,
          },
        });
        return NextResponse.json(updateUserPassword, { status: 200 });
      } else {
        console.log("passwords don't match");
        return NextResponse.json(
          { error: 'Passwords dont match' },
          { status: 404 }
        );
      }
    }
  );
}

One of the reasons Mosh talks about keeping functions short and simple and well organized is because of situations like this on. It’s challenging to decypher what’s going on here.

The problem is - you are passing a function to bcrypt.compare. That function returns a response object. But that return value is not passed outside the PUT() routine. It’s passed back from the bcrypt routine.

You have passwordCompare = bcrypt …

PasswordCompare is the result and is being assigned a Nextresponse object because of how you have all the logic inside the passed function.

If you want the quick fix - replace

const newPasswordProvidedAndHashed = await bcrypt.hash(
with
return bcrypt.hash(

But the real answer is to refactor all this into simple functions. You have functions inside of functions inside of functions. That’s why it’s complicated to decypher.

Jerry

Thanks @JerryHobby yes, it does look a bit complicated, I was following an implementation of becrypt.compare() that looked like this but I didn’t step back and think how to make it simpler. I’ll have a go at refactoring so see if that helps isolate where the issue is

Thanks for the advice @JerryHobby I went though again checking the docs and simplifying the steps, this was all that was needed to resolve the error, this now works.

import { NextRequest, NextResponse } from 'next/server';
import schema from '../resetPassword/schema';
import prisma from '@/prisma/client';
import bcrypt from 'bcrypt';

export async function PUT(request: NextRequest) {
  const body = await request.json();

  const validation = schema.safeParse(body);
  if (!validation.success)
    return NextResponse.json(validation.error.errors, { status: 400 });

  const user = await prisma.user.findUnique({
    where: { email: body.email },
  });

  if (!user)
    return NextResponse.json({ error: 'User not found' }, { status: 404 });

  const hashedPasswordFromDB = user.hashedPassword;

  const passwordsMatched = await bcrypt.compare(
    body.oldPassword,
    hashedPasswordFromDB!
  );

  if (!passwordsMatched) {
    return NextResponse.json({ error: 'Passwords dont match' }, { status: 404 });
  }

  if (passwordsMatched) {
    const newPasswordProvidedAndHashed = await bcrypt.hash(
      body.newPassword,
      10
    );

    const updateUserPassword = await prisma.user.update({
      where: { id: user.id },
      data: {
        email: body.email,
        hashedPassword: newPasswordProvidedAndHashed,
      },
    });

    return NextResponse.json(updateUserPassword, { status: 200 });
  }
}

Beautiful. Much easier to read and it works too!!
Jerry