Skip to content

added null checks for result properties. #194

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

amoscicki
Copy link

Brief description:

optional chaining added on property accessors, passing errors from proxy, allowing handling them on client side in nextjs

Bunch of folks (including me) were running into issues with error on accessing property on null object.
#103
When addressed by adding optional chaining it turned out that when authentication is unsuccessful, the error was the one providing feedback to the client side of the app, and by resolving issue auth errors were only visible on server end.
Added trivial passing errors in the response from nextjs proxy. This looks like a small can of worms as proper error handling should probably be introduced.
Since unsure on how maintainers would see best implementation of that, I left the fix at simplest possible implementation that can be built upon by adding matching type declarations on return type of signIn method of the convexAuth function

Errors themselves can look a bit rough as well and properly distinguishing between them is currently a little clunky as requires few splits and manual parsing of the message to get to the actual error type

example:

Error: [Request ID: 7a4755d4241579bb] Server Error\nUncaught Error: Could not verify code\n


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

passing errors in proxy, allowing handling on client in nextjs
Copy link

vercel bot commented Apr 21, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
convex-auth-docs ✅ Ready (Inspect) Visit Preview Apr 26, 2025 4:27pm

@amoscicki
Copy link
Author

I'm pretty certain this is not the intended place, meant to bubble up errors as errors cought there are not instances of ConvexError which I'd guess are the desired ones to be passed through. Happy to built upon this one more if you have any pointers.

@ghandic
Copy link

ghandic commented Apr 26, 2025

Very much requiring something like this as atm I'm not getting any errors thown in nextjs

Copy link

@ghandic ghandic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These needed to be changed for me so I could propagate to the frontend by raising a ConvexError

let response;
if (error instanceof Error && error.message) {
response = jsonResponse({
error: {
Copy link

@ghandic ghandic Apr 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (error instanceof ConvexError) {
        response = jsonResponse({
          error,
        });
      } 

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idea was to catch any error and the generic Error when stringified to JSON was returning empty object on the frontend in my tests.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I check using

if (error instanceof ConvexError) {
        logVerbose("error detected as ConvexError", verbose);
        response = jsonResponse({ error });
      } else if (error instanceof Error && error.message) {
        logVerbose("error detected as Error", verbose);
        response = jsonResponse({
          error: {
            name: error.name,
            message: error.message,
            stack: error.stack,
            cause: error.cause,
          },
        });
      } else {
        logVerbose("error detected as unknown", verbose);
        response = jsonResponse({ error });
      }

it logs [verbose] 2025-04-26T14:38:16.852Z [ConvexAuthNextjs] error detected as Error for me
I am testing with the OTP provider. Maybe other providers would return it differently?
even more reasons to have it handle all types as this likely shouldn't result in sending user to closes error boundary in nextjs when authentication fails.
IHMO this should be left for the consumer of the library to handle the way they want.

@@ -239,15 +239,19 @@ export function AuthProvider({
"auth:signIn" as unknown as SignInAction,
{ provider, params, verifier },
);
if (result.redirect !== undefined) {

if ("error" in result) throw new ConvexError(result.error);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if ("error" in result) throw new ConvexError(result.error.data);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if I read it right, idea would then be to only intercept ConvexError types? otherwise data may not exist on the result.error object.

await setAuthCookies(response, null, cookieConfig);
return response;
}
if (result.redirect !== undefined) {
if (result?.redirect !== undefined) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assuming these dont need modifying too as resposne is returned

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically no, but if something changes in future and for whatever reason it becomes null it shouldn't hurt to have check for null just in case. Happy to remove it though.

const { redirect } = result;
const response = jsonResponse({ redirect });
(await getResponseCookies(response, cookieConfig)).verifier =
result.verifier!;
logVerbose(`Redirecting to ${redirect}`, verbose);
return response;
} else if (result.tokens !== undefined) {
}
if (result?.tokens !== undefined) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assuming these dont need modifying too as resposne is returned

@ghandic
Copy link

ghandic commented Apr 26, 2025

I'm getting the errors on my frontend, imo I'd prefer to only propagate the errors to the frontend when known and without the full stack trace at it could expose too much detail and parsing it for use is difficult too

@ghandic
Copy link

ghandic commented Apr 26, 2025

I'm also waiting for convex to decide on their pathway either with this or with better auth, because some of the plugins from better auth would be bangin

@amoscicki
Copy link
Author

I'm getting the errors on my frontend, imo I'd prefer to only propagate the errors to the frontend when known and without the full stack trace at it could expose too much detail and parsing it for use is difficult too

Sure, the issue is that some of those seem to be the generic Error type which doesn't help. Also for stack trace not to be propagated in nextjs if I'm not mistaken you need to prevent any throws from the backend as by default those would be sent but client side will reroute you to closest error boundary component in your tree.

I'm also waiting for convex to decide on their pathway either with this or with better auth, because some of the plugins from better auth would be bangin

Yeah I've just seen some new thread appearance on discord. Wonder if that means this impl is to be deprecated?

@erquhart
Copy link
Collaborator

erquhart commented May 4, 2025

@amoscicki thanks so much for your work here. I have a smaller scope approach in #208 if you're up for trying it out. Want to fix this in the lowest impact way possible.

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

Successfully merging this pull request may close these issues.

3 participants