nuxt-auth icon indicating copy to clipboard operation
nuxt-auth copied to clipboard

Error 500 on Vercel deployment

Open Timothy16 opened this issue 2 years ago • 3 comments

Environment

No response

Reproduction

https://github.com/Timothy16/Rtechbizusers2.0 Demo is here: https://app-user-rtech.vercel.app/login

Steps to reproduce

  1. Register and check the profile page

Describe the bug

i deployed nuxt 3 app to vercel, when you visit the deployed link and login, all server/api call that requires auth token sometimes returns 500 on page mounted, and when you refresh or revisit the page it returns 200. I used sidebase_io for authentication. login, registration and API calls works perfectly locally.

I set my environment variable perfectly also on vercel

Additional context

.env

API_BASE= ""
AUTH_ORIGIN = ""

nuxt.config.ts

auth: {
      isEnabled: true,
      baseURL: process.env.AUTH_ORIGIN,
      provider: {
        type: 'authjs'
      },
  },

server/api/auth/[...].ts

import {NuxtAuthHandler} from "#auth";
import CredentialsProvider from "next-auth/providers/credentials";

const config = useRuntimeConfig()

export default NuxtAuthHandler({
  secret: "",
  pages: {
    signIn: '/login',
    signOut: '/login',
  },
  providers: [
    // @ts-ignore Import is exported on .default during SSR, so we need to call it this way. May be fixed via Vite at some point
    CredentialsProvider.default({
      name: "Credentials",
      credentials: {

      },
      profile(profile: any, tokens: any) {
        console.log('profile', profile)
        console.log('tokens', tokens)
        return {
          ...profile,
        }
      },
      async authorize(credentials: any) {

        // console.log('starting auth', credentials, config.API_BASE)
        // let response: any;
        try {
          const userToken = await $fetch<{
            
            data:{
              email: string;
              firstname: string;
              token: string | null,
              username: string;
            },
            message: string;
            // token: string | null,
            status: boolean,
            errors: any,
            }>(
            config.API_BASE+'/login',
            {
              method: "POST",
              body: {
                email: credentials.email,
                password: credentials.password,
              },
              headers: {
                "Content-Type": "application/json",
                "Accept-Language": "en-US",
              },
            }
          );
          
          const userDetail = await $fetch<{
            data:{
              id: string;
              email: string;
              name: string;
              phone: string;
              username: string;
              picture: string ;
              status: string;
              email_verified_at: string;
              last_seen: string | null;
              created_at?: string | null;
              updated_at?: string | null;
            }

          }>(
            config.API_BASE+'/user/profile',
            {
              method: "GET",
              headers: {
                "Content-Type": "application/json",
                "Accept-Language": "en-US",
                Authorization: `Bearer ${userToken?.data?.token}`,
              },
            }
          );

          if (!userToken || !userToken?.data?.token || !userDetail || !userDetail.data) {
            throw createError({
              statusCode: 422,
              statusMessage: "Invalid username or password",
            });
          }

          const userData = {
            id: userDetail.data.id,
            email: userDetail.data.email,
            name: userDetail.data.name,
            phone: userDetail.data.phone,
            username: userDetail.data.username,
            userStatus: userDetail.data.status,
            profileImgUrl: userDetail.data.picture,
            isEmailVerified: userDetail.data.email_verified_at,
            lastSeen: userDetail.data.last_seen,
            updatedAt: userDetail.data.updated_at,
            accessToken: userToken.data?.token
          };
         

          return userData
        } catch (error:any) {
          throw createError({
            statusCode: 422,
            statusMessage: "Invalid username or password",
          });

        }
      },
    }),
  ],
  session: {
    strategy: "jwt",
  },
  callbacks: {
    async jwt({ token, user, account, profile }) {
      if (account && user) {
        // console.warn("JWT callback", { token, user, account, profile });
        return {
          ...token,
          ...user,
        };
      }
      return token;
    },
    async session({ session, token, user }) {

      console.warn("Session callback", { token, session, user });

      session.user = {
        ...session.user,
        ...token
      };
      return session;
    },
  },
});

server/api/profile.ts


import { getToken } from '#auth'


const config = useRuntimeConfig()
export default defineEventHandler(async (event) => {

     let token = null

    const tokenp = await getToken({ event })

    if (tokenp) {
        token = tokenp.accessToken
    }
    
    if (event.method === 'GET') {
        
        const queryParams = getQuery(event)
        const newRequest = await $fetch(`${config.API_BASE}/user/profile`,
        {
            method: "GET",
            headers: {
                "Content-Type": "application/json",
                "Accept-Language": "en-US",
                Authorization: `Bearer ${token}`,
            },
            query: queryParams
        }).catch((error) => {
            throw createError({
                message: error.data.message,
                data: null,
                status: error.status,
            });
        })
        return newRequest
    }
    throw createError({
        message: "Invalid Url",
        status: 404,
        statusCode: 404,
        stack: undefined,
        data: null,

    });
})

Logs

No response

Timothy16 avatar Dec 18 '23 16:12 Timothy16

Hi! Do you have any server logs that can shed more light onto the problem? All I get from my testing in the browser is:

{
  "url": "/api/crypto",
  "statusCode": 500,
  "statusMessage": "",
  "message": "Error",
  "stack": ""
}

Which does not give me a lot to go off of 😓

I had a look into your source code and I am wondering where the request fails. I see on all the pages it:

  • Gets the Server Session
  • Makes a request to your external API

Could you verify that the request does not fail on your external api?

zoey-kaiser avatar Dec 18 '23 17:12 zoey-kaiser

@zoey-kaiser I don't have any server logs. Every request works perfectly locally and the external api also doesn't fail. Can you try cloning the project and test also try deploy to vercel

Timothy16 avatar Dec 18 '23 18:12 Timothy16

Maybe your error is not logged somehow. You can log the error by creating a nitro plugin, which hooks into the 'error' hook.

server/plugins/error-logging.ts:

export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('error', (error) => {
    console.error(error)
  })
})

DrJume avatar Jan 31 '24 10:01 DrJume

Please have a look at the new docs on deploying to Vercel. If the issue remains, please open a new issue 😊

zoey-kaiser avatar Jul 13 '24 10:07 zoey-kaiser