about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorHailey <me@haileyok.com>2024-05-01 01:08:59 -0700
committerGitHub <noreply@github.com>2024-05-01 01:08:59 -0700
commitb8d8bec388744c95aa84c955849d2bced45daf11 (patch)
tree987435632fae8bbfea56c935e6d55021356b636a /src
parent81ae7e425dc52846c5d4c282a0422a3875d84e2f (diff)
downloadvoidsky-b8d8bec388744c95aa84c955849d2bced45daf11.tar.zst
sentry errors for captcha web views and registration attempts (#3761)
* sentry errors for captcha web views

* include handles with errors

* log all registration request failures

* rm

* use a better trigger for web captcha errors

* add another trigger for recording a possible signup error

* unknown error type

* don't needlessly log on href errors

* honestly i probably cant always do a captcha in 20 seconds

* rm log

* timeout on back

* remove unnecessary colons
Diffstat (limited to 'src')
-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
-rw-r--r--src/screens/Signup/index.tsx11
-rw-r--r--src/screens/Signup/state.ts19
5 files changed, 60 insertions, 22 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>
diff --git a/src/screens/Signup/index.tsx b/src/screens/Signup/index.tsx
index 6758f7fa1..5e2596d8c 100644
--- a/src/screens/Signup/index.tsx
+++ b/src/screens/Signup/index.tsx
@@ -8,6 +8,7 @@ import {useAnalytics} from '#/lib/analytics/analytics'
 import {FEEDBACK_FORM_URL} from '#/lib/constants'
 import {logEvent} from '#/lib/statsig/statsig'
 import {createFullHandle} from '#/lib/strings/handles'
+import {logger} from '#/logger'
 import {useServiceQuery} from '#/state/queries/service'
 import {useAgent} from '#/state/session'
 import {LoggedOutLayout} from '#/view/com/util/layouts/LoggedOutLayout'
@@ -119,11 +120,19 @@ export function Signup({onPressBack}: {onPressBack: () => void}) {
 
   const onBackPress = React.useCallback(() => {
     if (state.activeStep !== SignupStep.INFO) {
+      if (state.activeStep === SignupStep.CAPTCHA) {
+        logger.error('Signup Flow Error', {
+          errorMessage:
+            'User went back from captcha step. Possibly encountered an error.',
+          registrationHandle: state.handle,
+        })
+      }
+
       dispatch({type: 'prev'})
     } else {
       onPressBack()
     }
-  }, [onPressBack, state.activeStep])
+  }, [onPressBack, state.activeStep, state.handle])
 
   return (
     <SignupContext.Provider value={{state, dispatch}}>
diff --git a/src/screens/Signup/state.ts b/src/screens/Signup/state.ts
index 86a144368..d6cf9c44c 100644
--- a/src/screens/Signup/state.ts
+++ b/src/screens/Signup/state.ts
@@ -246,6 +246,10 @@ export function useSubmitSignup({
         !verificationCode
       ) {
         dispatch({type: 'setStep', value: SignupStep.CAPTCHA})
+        logger.error('Signup Flow Error', {
+          errorMessage: 'Verification captcha code was not set.',
+          registrationHandle: state.handle,
+        })
         return dispatch({
           type: 'setError',
           value: _(msg`Please complete the verification captcha.`),
@@ -282,20 +286,17 @@ export function useSubmitSignup({
           return
         }
 
-        if ([400, 429].includes(e.status)) {
-          logger.warn('Failed to create account', {message: e})
-        } else {
-          logger.error(`Failed to create account (${e.status} status)`, {
-            message: e,
-          })
-        }
-
         const error = cleanError(errMsg)
         const isHandleError = error.toLowerCase().includes('handle')
 
         dispatch({type: 'setIsLoading', value: false})
-        dispatch({type: 'setError', value: cleanError(errMsg)})
+        dispatch({type: 'setError', value: error})
         dispatch({type: 'setStep', value: isHandleError ? 2 : 1})
+
+        logger.error('Signup Flow Error', {
+          errorMessage: error,
+          registrationHandle: state.handle,
+        })
       } finally {
         dispatch({type: 'setIsLoading', value: false})
       }