You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
exportasyncfunctionaction({ request }: ActionArgs){try{constform=awaitrequest.formData();validateEmail(form.get("email"));validatePasswordAndConfirmation(form.get("password"),form.get("password"));awaitauthenticator.authenticate("user-pass",request,{throwOnError: true,context: {formData: form},successRedirect: "/profile",});}catch(error){if(errorinstanceofAuthorizationError){returnjson({error: errorForToast(error.message)},{status: 401});}// Because redirects work by throwing a Response, it needs to be re-thrown.// Any other generic errors must also be thrown too.//// The "instanceof Response" line is added here for clarity, but "throw error"// would cover it already.if(errorinstanceofResponse)throwerror;throwerror;}}
If any kind of error is thrown internally, such Prisma throwing that the database is down, (
So effectively a prisma Error ends up being an AuthorizationError so it's treated no differently from user errors.
How can I determine what's an "AuthenticationError" such as wrong username, or password, which I'm doing by specifically throwing that error from within my Authenticator code [1], so that it's shown to users, versus internal server errors, that must not be displayed and should instead return a 500 or be caught by the CatchBoundary?
In my remix-auth-form strategy I'm specifically throwing AuthorizationError, but the way error handling is done it seems to cast a wider net:
exportconstauthUserWithEmailAndPassword=async({
inputEmail,
inputPassword,}: loginUserArgs): Promise<User>=>{constblacklisted=awaitexistsByDomainOrEmail(inputEmail);if(blacklisted){thrownewAuthorizationError("Sorry, your account has been suspended for breaching our Terms of Service.");}constuser=awaitgetUserByEmail(inputEmail);if(!user||!user.password){thrownewAuthorizationError("Incorrect email or password");}constpasswordMatches=awaitbcrypt.compare(inputPassword,user.password);if(!passwordMatches){awaitincrementFailedLogins(user);thrownewAuthorizationError("Incorrect email or password");}awaitcreateLoginRecord({userId: user.id,email: inputEmail});returnuser;
The text was updated successfully, but these errors were encountered:
SOLUTION: I needed to update to >= 1.3.0 to get access to the error.cause, which wraps the original error. Then it was a matter of updating my auth code to thrown a custom error instead, and when catching, check if error.cause is an instance of said error.
//login.tsxexportasyncfunctionaction({ request }: ActionArgs){try{constform=awaitrequest.formData();validateEmail(form.get("email"));validatePasswordAndConfirmation(form.get("password"),form.get("password"));awaitauthenticator.authenticate("user-pass",request,{throwOnError: true,context: {formData: form},successRedirect: "/profile",});}catch(error){if(errorinstanceofAuthorizationError&&error.causeinstanceofUserAuthError){returnjson({error: errorForToast(getErrorMessage(error))},{status: 401});}// Because redirects work by throwing a Response, it needs to be re-thrown.// Any other generic errors must also be thrown too.//// The "instanceof Response" line is added here for clarity, but "throw error"// would cover it already.if(errorinstanceofResponse)throwerror;throwerror;}}
Hey Sergio!
Given this action:
If any kind of error is thrown internally, such Prisma throwing that the database is down, (
remix-auth-form/src/index.ts
Line 36 in 5e3d408
this.failure
, and then it gets wrapped inAuthorizationError
by remix-auth here: https://github.com/sergiodxa/remix-auth/blob/d4e4f85745b13b0bbbb08bdd12375a91de48fd84/src/strategy.ts#LL125C35-L125C35So effectively a prisma Error ends up being an AuthorizationError so it's treated no differently from user errors.
How can I determine what's an "AuthenticationError" such as wrong username, or password, which I'm doing by specifically throwing that error from within my Authenticator code [1], so that it's shown to users, versus internal server errors, that must not be displayed and should instead return a 500 or be caught by the CatchBoundary?
In my remix-auth-form strategy I'm specifically throwing
AuthorizationError
, but the way error handling is done it seems to cast a wider net:The text was updated successfully, but these errors were encountered: