Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

couldn't handle custom error from authorize in frontend, using Vite, React and Hono.js #12479

Closed
QingjiaTsang opened this issue Jan 8, 2025 · 0 comments
Labels
bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.

Comments

@QingjiaTsang
Copy link

QingjiaTsang commented Jan 8, 2025

Environment

node version: v20.13.1
not using nextjs, only vite, react for frontend and honojs for backend
here's the deps:

    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "@auth/core": "^0.37.4",
    "@hono/auth-js": "^1.0.15",

Reproduction URL

https://github.com/QingjiaTsang/reproduce-authjs-issue

Describe the issue

I have followed the docs guide, but failed.
https://authjs.dev/getting-started/providers/credentials#custom-error-messages

In honojs auth config file, I tried to throw a custom error from authorize:

// apps/api/src/lib/create-auth-config.ts
import type { AuthConfig } from "@hono/auth-js";

import { AuthError, CredentialsSignin } from "@auth/core/errors";
import { encode } from "@auth/core/jwt";
import Credentials from "@auth/core/providers/credentials";
import GitHub from "@auth/core/providers/github";
import Google from "@auth/core/providers/google";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import { drizzle } from "drizzle-orm/d1";
import { v4 as uuidv4 } from "uuid";

import type { AppEnv } from "./types";

import { getUserFromDb } from "./auth-utils";

class InvalidLoginError extends CredentialsSignin {
  code = "custom-error-code";
}

export default function createAuthConfig(env: AppEnv["Bindings"]): AuthConfig {
  const adapter = DrizzleAdapter(drizzle(env.DB));
  const db = drizzle(env.DB);

  return {
    adapter,
    secret: env.AUTH_SECRET,
    providers: [
      GitHub({
        clientId: env.GITHUB_CLIENT_ID,
        clientSecret: env.GITHUB_CLIENT_SECRET,
      }),
      Google({
        clientId: env.AUTH_GOOGLE_ID,
        clientSecret: env.AUTH_GOOGLE_SECRET,
      }),
      Credentials({
        credentials: {
          email: {
            label: "Email",
            type: "email",
            placeholder: "Please enter your email",
          },
          password: {
            label: "Password",
            type: "password",
            placeholder: "Please enter your password",
          },
        },
        async authorize(credentials) {
          if (!credentials?.email || !credentials?.password) {
            return null;
          }

          const result = await getUserFromDb(db, credentials.email as string, credentials.password as string);

          // Wrong password or email not verified
          if (!result.success) {
            throw new InvalidLoginError("my custom error");
            // throw new InvalidLoginError(result.message)
          }

          return result.user!;
        },
      }),
    ],
    callbacks: {
      async jwt({ token, account }) {
        if (account?.provider === "credentials") {
          token.credentials = true;
        }
        return token;
      },
    },
    jwt: {
      encode: async (params) => {
        if (params.token?.credentials) {
          const sessionToken = uuidv4();

          if (!params.token.sub) {
            throw new Error("No user ID found in token");
          }

          const createdSession = await adapter.createSession?.(
            {
              sessionToken,
              userId: params.token.sub,
              expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30), // 30 days
            },
          );

          if (!createdSession) {
            throw new Error("Failed to create session");
          }

          return sessionToken;
        }

        return await encode(params);
      },
    },
  };
}

But it failed to catch that in frontend:

  // apps/web/src/services/auth/api.ts
  credentialSignin: async (data: CredentialsSchema & { callbackUrl?: string }) => {
    try {
      const response = await signIn("credentials", {
        ...data,
        callbackUrl: data.callbackUrl,
        redirect: false,
      });

      console.log({
        response,
      });

      return response;
    }
    catch (error) {
      // throw new Error(error.message);
      console.error(error);
    }
  },

It always prints like this, no matter how I tried the solutions relative to this issue in the github (like creating a custom Error class extended from CredentialsSignin or AuthError), it always can't bring the custom error message out. So I guess those solutions there maybe only work for nextjs, and I'm using vite, React and Honojs, it doesn't have the server side like server action in nextjs.
Google Chrome 2025-01-08 13 11 39

How to reproduce

  1. run commands below:
pnpm i

pnpm dlx wrangler d1 create replace-with-your-database-name-here

pnpm run -r db:migrate:local

pnpm dev
  1. get to the /signin route and type any email and password to trigger the error from auth.js and open the devtools console to see what it looks like.

Expected behavior

have an easy access to handle the custom error thrown from authorize in frontend

@QingjiaTsang QingjiaTsang added bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime. labels Jan 8, 2025
@QingjiaTsang QingjiaTsang changed the title couldn't handle custom error from authorize in frontend couldn't handle custom error from authorize in frontend, using Vite, React and Hono.js Jan 8, 2025
@nextauthjs nextauthjs locked and limited conversation to collaborators Jan 12, 2025
@ThangHuuVu ThangHuuVu converted this issue into discussion #12495 Jan 12, 2025

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.
Projects
None yet
Development

No branches or pull requests

1 participant