fix: stop grouping all signup failures into one sentry issue
Fixes APP-S3WR Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -103,6 +103,10 @@ export type Events = {
|
|||||||
}
|
}
|
||||||
'signup:captchaSuccess': {}
|
'signup:captchaSuccess': {}
|
||||||
'signup:captchaFailure': {}
|
'signup:captchaFailure': {}
|
||||||
|
'signup:captchaBackPress': {}
|
||||||
|
'signup:createAccountFailure': {
|
||||||
|
reason: string
|
||||||
|
}
|
||||||
'signup:fieldError': {
|
'signup:fieldError': {
|
||||||
field: string
|
field: string
|
||||||
errorCount: number
|
errorCount: number
|
||||||
|
|||||||
@@ -127,23 +127,17 @@ function StepCaptchaInner({
|
|||||||
value: _(msg`Error receiving captcha response.`),
|
value: _(msg`Error receiving captcha response.`),
|
||||||
})
|
})
|
||||||
ax.metric('signup:captchaFailure', {})
|
ax.metric('signup:captchaFailure', {})
|
||||||
logger.error('Signup Flow Error', {
|
logger.error('Signup: captcha response error', {
|
||||||
registrationHandle: state.handle,
|
safeMessage: error,
|
||||||
error,
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
[_, ax, dispatch, state.handle],
|
[_, ax, dispatch],
|
||||||
)
|
)
|
||||||
|
|
||||||
const onBackPress = useCallback(() => {
|
const onBackPress = useCallback(() => {
|
||||||
logger.error('Signup Flow Error', {
|
ax.metric('signup:captchaBackPress', {})
|
||||||
errorMessage:
|
|
||||||
'User went back from captcha step. Possibly encountered an error.',
|
|
||||||
registrationHandle: state.handle,
|
|
||||||
})
|
|
||||||
|
|
||||||
dispatch({type: 'prev'})
|
dispatch({type: 'prev'})
|
||||||
}, [dispatch, state.handle])
|
}, [ax, dispatch])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
+30
-10
@@ -8,7 +8,7 @@ import {useLingui} from '@lingui/react/macro'
|
|||||||
import * as EmailValidator from 'email-validator'
|
import * as EmailValidator from 'email-validator'
|
||||||
|
|
||||||
import {DEFAULT_SERVICE} from '#/lib/constants'
|
import {DEFAULT_SERVICE} from '#/lib/constants'
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError, isNetworkError} from '#/lib/strings/errors'
|
||||||
import {createFullHandle} from '#/lib/strings/handles'
|
import {createFullHandle} from '#/lib/strings/handles'
|
||||||
import {getAge} from '#/lib/strings/time'
|
import {getAge} from '#/lib/strings/time'
|
||||||
import {useSessionApi} from '#/state/session'
|
import {useSessionApi} from '#/state/session'
|
||||||
@@ -255,6 +255,25 @@ export const SignupContext = createContext<IContext>({} as IContext)
|
|||||||
SignupContext.displayName = 'SignupContext'
|
SignupContext.displayName = 'SignupContext'
|
||||||
export const useSignupContext = () => useContext(SignupContext)
|
export const useSignupContext = () => useContext(SignupContext)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a PII-free name for expected signup failures, or undefined if the
|
||||||
|
* failure is unexpected and should be reported to Sentry.
|
||||||
|
*/
|
||||||
|
function classifyExpectedSignupError(e: unknown): string | undefined {
|
||||||
|
if (e instanceof ComAtprotoServerCreateAccount.InvalidHandleError)
|
||||||
|
return 'InvalidHandle'
|
||||||
|
if (e instanceof ComAtprotoServerCreateAccount.HandleNotAvailableError)
|
||||||
|
return 'HandleNotAvailable'
|
||||||
|
if (e instanceof ComAtprotoServerCreateAccount.InvalidPasswordError)
|
||||||
|
return 'InvalidPassword'
|
||||||
|
if (e instanceof ComAtprotoServerCreateAccount.UnsupportedDomainError)
|
||||||
|
return 'UnsupportedDomain'
|
||||||
|
/* the server sends no typed error for this case */
|
||||||
|
if (String(e).includes('Email already taken')) return 'EmailTaken'
|
||||||
|
if (isNetworkError(e)) return 'NetworkError'
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
export function useSubmitSignup() {
|
export function useSubmitSignup() {
|
||||||
const ax = useAnalytics()
|
const ax = useAnalytics()
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
@@ -300,10 +319,7 @@ export function useSubmitSignup() {
|
|||||||
!state.pendingSubmit?.verificationCode
|
!state.pendingSubmit?.verificationCode
|
||||||
) {
|
) {
|
||||||
dispatch({type: 'setStep', value: SignupStep.CAPTCHA})
|
dispatch({type: 'setStep', value: SignupStep.CAPTCHA})
|
||||||
ax.logger.error('Signup Flow Error', {
|
ax.logger.error('Signup: captcha code missing at submit', {})
|
||||||
errorMessage: 'Verification captcha code was not set.',
|
|
||||||
registrationHandle: state.handle,
|
|
||||||
})
|
|
||||||
return dispatch({
|
return dispatch({
|
||||||
type: 'setError',
|
type: 'setError',
|
||||||
value: l`Please complete the verification captcha.`,
|
value: l`Please complete the verification captcha.`,
|
||||||
@@ -362,14 +378,18 @@ export function useSubmitSignup() {
|
|||||||
})
|
})
|
||||||
dispatch({type: 'setStep', value: isHandleError ? 2 : 1})
|
dispatch({type: 'setStep', value: isHandleError ? 2 : 1})
|
||||||
|
|
||||||
ax.logger.error('Signup Flow Error', {
|
const expected = classifyExpectedSignupError(e)
|
||||||
errorMessage: error,
|
if (expected) {
|
||||||
registrationHandle: state.handle,
|
ax.metric('signup:createAccountFailure', {reason: expected})
|
||||||
})
|
} else {
|
||||||
|
ax.logger.error('Signup: unexpected createAccount failure', {
|
||||||
|
safeMessage: e,
|
||||||
|
})
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
dispatch({type: 'setIsLoading', value: false})
|
dispatch({type: 'setIsLoading', value: false})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[l, ax.logger, createAccount, onboardingDispatch],
|
[l, ax, createAccount, onboardingDispatch],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user