about summary refs log tree commit diff
path: root/src/screens/Signup/StepCaptcha
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens/Signup/StepCaptcha')
-rw-r--r--src/screens/Signup/StepCaptcha/CaptchaWebView.tsx10
-rw-r--r--src/screens/Signup/StepCaptcha/CaptchaWebView.web.tsx22
-rw-r--r--src/screens/Signup/StepCaptcha/index.tsx20
3 files changed, 40 insertions, 12 deletions
diff --git a/src/screens/Signup/StepCaptcha/CaptchaWebView.tsx b/src/screens/Signup/StepCaptcha/CaptchaWebView.tsx
index 50918c4ce..caa0aa28a 100644
--- a/src/screens/Signup/StepCaptcha/CaptchaWebView.tsx
+++ b/src/screens/Signup/StepCaptcha/CaptchaWebView.tsx
@@ -26,7 +26,7 @@ export function CaptchaWebView({
   stateParam: string
   state?: SignupState
   onSuccess: (code: string) => void
-  onError: () => void
+  onError: (error: unknown) => void
 }) {
   const redirectHost = React.useMemo(() => {
     if (!state?.serviceUrl) return 'bsky.app'
@@ -56,7 +56,7 @@ export function CaptchaWebView({
 
       const code = urlp.searchParams.get('code')
       if (urlp.searchParams.get('state') !== stateParam || !code) {
-        onError()
+        onError({error: 'Invalid state or code'})
         return
       }
 
@@ -74,6 +74,12 @@ export function CaptchaWebView({
       onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
       onNavigationStateChange={onNavigationStateChange}
       scrollEnabled={false}
+      onError={e => {
+        onError(e.nativeEvent)
+      }}
+      onHttpError={e => {
+        onError(e.nativeEvent)
+      }}
     />
   )
 }
diff --git a/src/screens/Signup/StepCaptcha/CaptchaWebView.web.tsx b/src/screens/Signup/StepCaptcha/CaptchaWebView.web.tsx
index 7791a58dd..8faaf90a0 100644
--- a/src/screens/Signup/StepCaptcha/CaptchaWebView.web.tsx
+++ b/src/screens/Signup/StepCaptcha/CaptchaWebView.web.tsx
@@ -13,8 +13,20 @@ export function CaptchaWebView({
   url: string
   stateParam: string
   onSuccess: (code: string) => void
-  onError: () => void
+  onError: (error: unknown) => void
 }) {
+  React.useEffect(() => {
+    const timeout = setTimeout(() => {
+      onError({
+        errorMessage: 'User did not complete the captcha within 30 seconds',
+      })
+    }, 30e3)
+
+    return () => {
+      clearTimeout(timeout)
+    }
+  }, [onError])
+
   const onLoad = React.useCallback(() => {
     // @ts-ignore web
     const frame: HTMLIFrameElement = document.getElementById(
@@ -32,12 +44,14 @@ export function CaptchaWebView({
 
       const code = urlp.searchParams.get('code')
       if (urlp.searchParams.get('state') !== stateParam || !code) {
-        onError()
+        onError({error: 'Invalid state or code'})
         return
       }
       onSuccess(code)
-    } catch (e) {
-      // We don't need to handle this
+    } catch (e: unknown) {
+      // We don't actually want to record an error here, because this will happen quite a bit. We will only be able to
+      // get hte href of the iframe if it's on our domain, so all the hcaptcha requests will throw here, although it's
+      // harmless. Our other indicators of time-to-complete and back press should be more reliable in catching issues.
     }
   }, [stateParam, onSuccess, onError])
 
diff --git a/src/screens/Signup/StepCaptcha/index.tsx b/src/screens/Signup/StepCaptcha/index.tsx
index 2429b0c5e..d0fc4e934 100644
--- a/src/screens/Signup/StepCaptcha/index.tsx
+++ b/src/screens/Signup/StepCaptcha/index.tsx
@@ -5,6 +5,7 @@ import {useLingui} from '@lingui/react'
 import {nanoid} from 'nanoid/non-secure'
 
 import {createFullHandle} from '#/lib/strings/handles'
+import {logger} from '#/logger'
 import {ScreenTransition} from '#/screens/Login/ScreenTransition'
 import {useSignupContext, useSubmitSignup} from '#/screens/Signup/state'
 import {CaptchaWebView} from '#/screens/Signup/StepCaptcha/CaptchaWebView'
@@ -43,12 +44,19 @@ export function StepCaptcha() {
     [submit],
   )
 
-  const onError = React.useCallback(() => {
-    dispatch({
-      type: 'setError',
-      value: _(msg`Error receiving captcha response.`),
-    })
-  }, [_, dispatch])
+  const onError = React.useCallback(
+    (error?: unknown) => {
+      dispatch({
+        type: 'setError',
+        value: _(msg`Error receiving captcha response.`),
+      })
+      logger.error('Signup Flow Error', {
+        registrationHandle: state.handle,
+        error,
+      })
+    },
+    [_, dispatch, state.handle],
+  )
 
   return (
     <ScreenTransition>