Skip to content

Commit c37b4ec

Browse files
committed
handle all auth api errors
1 parent 6ae13b1 commit c37b4ec

File tree

4 files changed

+114
-26
lines changed

4 files changed

+114
-26
lines changed

site/src/components/SignInForm/SignInForm.stories.tsx

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const Template: Story<SignInFormProps> = (args: SignInFormProps) => <SignInForm
1515
export const SignedOut = Template.bind({})
1616
SignedOut.args = {
1717
isLoading: false,
18-
authError: undefined,
18+
loginErrors: {},
1919
onSubmit: () => {
2020
return Promise.resolve()
2121
},
@@ -34,29 +34,82 @@ Loading.args = {
3434
export const WithLoginError = Template.bind({})
3535
WithLoginError.args = {
3636
...SignedOut.args,
37-
authError: {
38-
response: {
39-
data: {
40-
message: "Email or password was invalid",
41-
validations: [
42-
{
43-
field: "password",
44-
detail: "Password is invalid.",
45-
},
46-
],
37+
loginErrors: {
38+
authError: {
39+
response: {
40+
data: {
41+
message: "Email or password was invalid",
42+
validations: [
43+
{
44+
field: "password",
45+
detail: "Password is invalid.",
46+
},
47+
],
48+
},
4749
},
50+
isAxiosError: true,
4851
},
49-
isAxiosError: true,
5052
},
5153
initialTouched: {
5254
password: true,
5355
},
5456
}
5557

58+
export const WithGetUserError = Template.bind({})
59+
WithGetUserError.args = {
60+
...SignedOut.args,
61+
loginErrors: {
62+
getUserError: {
63+
response: {
64+
data: {
65+
message: "Unable to fetch user details",
66+
detail: "Resource not found or you do not have access to this resource.",
67+
},
68+
},
69+
isAxiosError: true,
70+
},
71+
},
72+
}
73+
74+
export const WithCheckPermissionsError = Template.bind({})
75+
WithCheckPermissionsError.args = {
76+
...SignedOut.args,
77+
loginErrors: {
78+
checkPermissionsError: {
79+
response: {
80+
data: {
81+
message: "Unable to fetch user permissions",
82+
detail: "Resource not found or you do not have access to this resource.",
83+
},
84+
},
85+
isAxiosError: true,
86+
},
87+
},
88+
}
89+
5690
export const WithAuthMethodsError = Template.bind({})
5791
WithAuthMethodsError.args = {
5892
...SignedOut.args,
59-
methodsError: new Error("Failed to fetch auth methods"),
93+
loginErrors: {
94+
getMethodsError: new Error("Failed to fetch auth methods"),
95+
},
96+
}
97+
98+
export const WithGetUserAndAuthMethodsErrors = Template.bind({})
99+
WithGetUserAndAuthMethodsErrors.args = {
100+
...SignedOut.args,
101+
loginErrors: {
102+
getUserError: {
103+
response: {
104+
data: {
105+
message: "Unable to fetch user details",
106+
detail: "Resource not found or you do not have access to this resource.",
107+
},
108+
},
109+
isAxiosError: true,
110+
},
111+
getMethodsError: new Error("Failed to fetch auth methods"),
112+
},
60113
}
61114

62115
export const WithGithub = Template.bind({})

site/src/components/SignInForm/SignInForm.tsx

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ export const Language = {
2929
emailInvalid: "Please enter a valid email address.",
3030
emailRequired: "Please enter an email address.",
3131
authErrorMessage: "Incorrect email or password.",
32-
methodsErrorMessage: "Unable to fetch auth methods.",
32+
getUserErrorMessage: "Unable to fetch user details.",
33+
checkPermissionsErrorMessage: "Unable to fetch user permissions.",
34+
getMethodsErrorMessage: "Unable to fetch auth methods.",
3335
passwordSignIn: "Sign In",
3436
githubSignIn: "GitHub",
3537
}
@@ -65,11 +67,17 @@ const useStyles = makeStyles((theme) => ({
6567
},
6668
}))
6769

70+
type LoginErrors = {
71+
authError?: Error | unknown
72+
getUserError?: Error | unknown
73+
checkPermissionsError?: Error | unknown
74+
getMethodsError?: Error | unknown
75+
}
76+
6877
export interface SignInFormProps {
6978
isLoading: boolean
7079
redirectTo: string
71-
authError?: Error | unknown
72-
methodsError?: Error | unknown
80+
loginErrors: LoginErrors
7381
authMethods?: AuthMethods
7482
onSubmit: ({ email, password }: { email: string; password: string }) => Promise<void>
7583
// initialTouched is only used for testing the error state of the form.
@@ -80,8 +88,7 @@ export const SignInForm: FC<SignInFormProps> = ({
8088
authMethods,
8189
redirectTo,
8290
isLoading,
83-
authError,
84-
methodsError,
91+
loginErrors,
8592
onSubmit,
8693
initialTouched,
8794
}) => {
@@ -101,18 +108,39 @@ export const SignInForm: FC<SignInFormProps> = ({
101108
onSubmit,
102109
initialTouched,
103110
})
104-
const getFieldHelpers = getFormHelpersWithError<BuiltInAuthFormValues>(form, authError)
111+
const getFieldHelpers = getFormHelpersWithError<BuiltInAuthFormValues>(
112+
form,
113+
loginErrors.authError,
114+
)
105115

106116
return (
107117
<>
108118
<Welcome />
109119
<form onSubmit={form.handleSubmit}>
110120
<Stack>
111-
{authError && (
112-
<ErrorSummary error={authError} defaultMessage={Language.authErrorMessage} />
121+
{loginErrors.authError && (
122+
<ErrorSummary
123+
error={loginErrors.authError}
124+
defaultMessage={Language.authErrorMessage}
125+
/>
126+
)}
127+
{loginErrors.getUserError && (
128+
<ErrorSummary
129+
error={loginErrors.getUserError}
130+
defaultMessage={Language.getUserErrorMessage}
131+
/>
132+
)}
133+
{loginErrors.checkPermissionsError && (
134+
<ErrorSummary
135+
error={loginErrors.checkPermissionsError}
136+
defaultMessage={Language.checkPermissionsErrorMessage}
137+
/>
113138
)}
114-
{methodsError && (
115-
<ErrorSummary error={methodsError} defaultMessage={Language.methodsErrorMessage} />
139+
{loginErrors.getMethodsError && (
140+
<ErrorSummary
141+
error={loginErrors.getMethodsError}
142+
defaultMessage={Language.getMethodsErrorMessage}
143+
/>
116144
)}
117145
<TextField
118146
{...getFieldHelpers("email")}

site/src/pages/LoginPage/LoginPage.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export const LoginPage: React.FC = () => {
4040
authSend({ type: "SIGN_IN", email, password })
4141
}
4242

43+
const { authError, getUserError, checkPermissionsError, getMethodsError } = authState.context
44+
4345
if (authState.matches("signedIn")) {
4446
return <Navigate to={redirectTo} replace />
4547
} else {
@@ -54,8 +56,12 @@ export const LoginPage: React.FC = () => {
5456
authMethods={authState.context.methods}
5557
redirectTo={redirectTo}
5658
isLoading={isLoading}
57-
authError={authState.context.authError}
58-
methodsError={authState.context.getMethodsError as Error}
59+
loginErrors={{
60+
authError,
61+
getUserError,
62+
checkPermissionsError,
63+
getMethodsError,
64+
}}
5965
onSubmit={onSubmit}
6066
/>
6167
</div>

site/src/xServices/auth/authXService.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,13 @@ export const authMachine =
213213
tags: "loading",
214214
},
215215
gettingUser: {
216+
entry: "clearGetUserError",
216217
invoke: {
217218
src: "getMe",
218219
id: "getMe",
219220
onDone: [
220221
{
221-
actions: ["assignMe", "clearGetUserError"],
222+
actions: ["assignMe"],
222223
target: "gettingPermissions",
223224
},
224225
],

0 commit comments

Comments
 (0)