Handle invalid error in the request form
Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
@@ -58,6 +58,18 @@ export class ForbiddenError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class InvalidError extends Error {
|
||||||
|
field?: string;
|
||||||
|
cause?: string;
|
||||||
|
|
||||||
|
constructor(message?: string, field?: string, cause?: string) {
|
||||||
|
super(message || "INVALID");
|
||||||
|
this.name = "InvalidError";
|
||||||
|
this.field = field;
|
||||||
|
this.cause = cause;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function buildEndpoint(path: string): string {
|
export function buildEndpoint(path: string): string {
|
||||||
const host = import.meta.env.VITE_API_URL;
|
const host = import.meta.env.VITE_API_URL;
|
||||||
|
|
||||||
@@ -91,6 +103,9 @@ const hasUnauthorizedError = (error: GraphQLError) =>
|
|||||||
const hasForbiddenError = (error: GraphQLError) =>
|
const hasForbiddenError = (error: GraphQLError) =>
|
||||||
error.extensions?.code == "FORBIDDEN";
|
error.extensions?.code == "FORBIDDEN";
|
||||||
|
|
||||||
|
const hasInvalidError = (error: GraphQLError) =>
|
||||||
|
error.extensions?.code == "INVALID_REQUEST";
|
||||||
|
|
||||||
const fetchRelay: FetchFunction = async (
|
const fetchRelay: FetchFunction = async (
|
||||||
request,
|
request,
|
||||||
variables,
|
variables,
|
||||||
@@ -183,6 +198,15 @@ const fetchRelay: FetchFunction = async (
|
|||||||
if (forbiddenError) {
|
if (forbiddenError) {
|
||||||
throw new ForbiddenError(forbiddenError.message);
|
throw new ForbiddenError(forbiddenError.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const invalidError = errors.find(hasInvalidError);
|
||||||
|
if (invalidError) {
|
||||||
|
throw new InvalidError(
|
||||||
|
invalidError.message,
|
||||||
|
invalidError.extensions.field as string ?? "",
|
||||||
|
invalidError.extensions.cause as string ?? "",
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { useMutationWithToasts } from "/hooks/useMutationWithToast";
|
|||||||
import { useTrustCenter } from "/hooks/useTrustCenter";
|
import { useTrustCenter } from "/hooks/useTrustCenter";
|
||||||
import { type FormEventHandler, type PropsWithChildren } from "react";
|
import { type FormEventHandler, type PropsWithChildren } from "react";
|
||||||
import { useIsAuthenticated } from "/hooks/useIsAuthenticated.ts";
|
import { useIsAuthenticated } from "/hooks/useIsAuthenticated.ts";
|
||||||
|
import { InvalidError } from "/providers/RelayProviders";
|
||||||
|
|
||||||
type Props = PropsWithChildren<{
|
type Props = PropsWithChildren<{
|
||||||
documentId?: string;
|
documentId?: string;
|
||||||
@@ -40,7 +41,7 @@ export function RequestAccessDialog({
|
|||||||
const trustCenter = useTrustCenter();
|
const trustCenter = useTrustCenter();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
const { handleSubmit, register } = useFormWithSchema(schema, {
|
const { handleSubmit, register, setError, formState } = useFormWithSchema(schema, {
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
name: "",
|
name: "",
|
||||||
email: "",
|
email: "",
|
||||||
@@ -62,7 +63,11 @@ export function RequestAccessDialog({
|
|||||||
dialogRef.current?.close();
|
dialogRef.current?.close();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
if (error instanceof InvalidError) {
|
||||||
|
if (error.field === "email") {
|
||||||
|
setError(error.field, {message: error.message})
|
||||||
|
}
|
||||||
|
}
|
||||||
toast({
|
toast({
|
||||||
title: __("Error"),
|
title: __("Error"),
|
||||||
description: __("Cannot request access"),
|
description: __("Cannot request access"),
|
||||||
@@ -109,6 +114,7 @@ export function RequestAccessDialog({
|
|||||||
placeholder="john.doe@acme.com"
|
placeholder="john.doe@acme.com"
|
||||||
{...register("email")}
|
{...register("email")}
|
||||||
type="email"
|
type="email"
|
||||||
|
error={formState.errors.email?.message}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -16,6 +16,18 @@ export class UnAuthenticatedError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class InvalidError extends Error {
|
||||||
|
field?: string;
|
||||||
|
cause?: string;
|
||||||
|
|
||||||
|
constructor(message?: string, field?: string, cause?: string) {
|
||||||
|
super(message || "INVALID");
|
||||||
|
this.name = "InvalidError";
|
||||||
|
this.field = field;
|
||||||
|
this.cause = cause;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class InternalServerError extends Error {
|
export class InternalServerError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("INTERNAL_SERVER_ERROR");
|
super("INTERNAL_SERVER_ERROR");
|
||||||
@@ -47,6 +59,9 @@ export function buildEndpoint(path: string): string {
|
|||||||
const hasUnauthenticatedError = (error: GraphQLError) =>
|
const hasUnauthenticatedError = (error: GraphQLError) =>
|
||||||
error.extensions?.code == "UNAUTHENTICATED";
|
error.extensions?.code == "UNAUTHENTICATED";
|
||||||
|
|
||||||
|
const hasInvalidError = (error: GraphQLError) =>
|
||||||
|
error.extensions?.code == "INVALID_REQUEST";
|
||||||
|
|
||||||
const fetchRelay: FetchFunction = async (
|
const fetchRelay: FetchFunction = async (
|
||||||
request,
|
request,
|
||||||
variables,
|
variables,
|
||||||
@@ -125,6 +140,15 @@ const fetchRelay: FetchFunction = async (
|
|||||||
throw new UnAuthenticatedError();
|
throw new UnAuthenticatedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const invalidError = errors.find(hasInvalidError);
|
||||||
|
if (invalidError) {
|
||||||
|
throw new InvalidError(
|
||||||
|
invalidError.message,
|
||||||
|
invalidError.extensions.field as string ?? "",
|
||||||
|
invalidError.extensions.cause as string ?? "",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error(`Error fetching GraphQL query '${request.name}'`);
|
throw new Error(`Error fetching GraphQL query '${request.name}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,9 +58,9 @@ const (
|
|||||||
func (tcar *TrustCenterAccessRequest) Validate() error {
|
func (tcar *TrustCenterAccessRequest) Validate() error {
|
||||||
v := validator.New()
|
v := validator.New()
|
||||||
|
|
||||||
v.Check(tcar.Email, "email", validator.NotOneOfSlice([]string{}))
|
v.Check(tcar.Email, "email", validator.NotBlacklisted())
|
||||||
|
|
||||||
return nil
|
return v.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TrustCenterAccessService) ValidateToken(
|
func (s TrustCenterAccessService) ValidateToken(
|
||||||
@@ -88,7 +88,7 @@ func (s TrustCenterAccessService) Request(
|
|||||||
req *TrustCenterAccessRequest,
|
req *TrustCenterAccessRequest,
|
||||||
) (*coredata.TrustCenterAccess, error) {
|
) (*coredata.TrustCenterAccess, error) {
|
||||||
if err := req.Validate(); err != nil {
|
if err := req.Validate(); err != nil {
|
||||||
return nil, fmt.Errorf("invalid request arguments")
|
return nil, fmt.Errorf("invalid request arguments: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func NotBlacklisted() ValidatorFunc {
|
|||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return newValidationError(
|
return newValidationError(
|
||||||
ErrorCodeInvalidEnum,
|
ErrorCodeInvalidEmail,
|
||||||
"must not be blacklisted",
|
"must not be blacklisted",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user