Skip to content

Commit

Permalink
feature: add extra error handling and retires
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Waldstein committed Oct 7, 2024
1 parent 62c97c5 commit cc2be83
Showing 1 changed file with 32 additions and 8 deletions.
40 changes: 32 additions & 8 deletions src/FormExtension/DonationForm/resources/js/TurnstileField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ import {GiveWP, TurnstileFieldSettings} from './types';

declare const window: GiveWP & TurnstileFieldSettings & Window;

/**
* Check if the error is a required field error.
* @since 1.0.0
*/
const isRequiredError = (error: {message: string, type: string}) => error.message === 'This is a required field' || error.type === 'string.empty';

/**
* Error codes that should trigger a retry of the Turnstile challenge.
* @since 1.0.0
*/
const errorCodeRetry = {
/**
* 11060*: Challenge timed out: The visitor took too long to solve the challenge and the challenge timed out.
* 11062*: Challenge timed out: This error is for visible mode only. The visitor took too long to solve the interactive challenge and the challenge became outdated.
*/
challengeTimeout: ['11060', '11062']
};

/**
* @since 1.0.0
*/
Expand All @@ -16,15 +34,16 @@ export default function TurnstileField({
}) {
const ref = useRef<TurnstileInstance | null>(null);
const { setValue, setError } = window.givewp.form.hooks.useFormContext();
const { submitCount } = window.givewp.form.hooks.useFormState();
const { submitCount, errors } = window.givewp.form.hooks.useFormState();
const fieldName = inputProps.name;
const setFormError = useCallback(() =>
setError('FORM_ERROR', {
message: __('You must be a human.', 'give')
}), [setError]
);

useEffect(() => {
if (fieldError && fieldError !== 'This is a required field') {
if (fieldError && errors && fieldName in errors && isRequiredError(errors[fieldName])) {
setFormError();
}
}, [fieldError]);
Expand All @@ -40,13 +59,18 @@ export default function TurnstileField({
<Turnstile
ref={ref}
siteKey={window.giveTurnstileFieldSettings.siteKey}
onError={() => {
setFormError();
}
}
onError={(errorCode: string) => {
console.error({ turnstileError: errorCode });

if (errorCodeRetry.challengeTimeout.some(code => errorCode.startsWith(code))) {
ref.current?.reset();
} else {
setFormError();
}
}}
onExpire={() => ref.current?.reset()}
onSuccess={value => {
setValue(inputProps.name, value);
onSuccess={(value: string) => {
setValue(fieldName, value);
}}
/>

Expand Down

0 comments on commit cc2be83

Please sign in to comment.