diff --git a/site/src/api/errors.ts b/site/src/api/errors.ts
index 80c93dfe6dada..f16f422154848 100644
--- a/site/src/api/errors.ts
+++ b/site/src/api/errors.ts
@@ -44,3 +44,12 @@ export const mapApiErrorToFieldErrors = (apiErrorResponse: ApiErrorResponse): Fi
return result
}
+
+/**
+ *
+ * @param error
+ * @param defaultMessage
+ * @returns error's message if ApiError or Error, else defaultMessage
+ */
+export const getErrorMessage = (error: Error | ApiError | unknown, defaultMessage: string): string =>
+ isApiError(error) ? error.response.data.message : error instanceof Error ? error.message : defaultMessage
diff --git a/site/src/pages/UsersPage/UsersPage.test.tsx b/site/src/pages/UsersPage/UsersPage.test.tsx
index 3e4b300b101af..086990a920d2e 100644
--- a/site/src/pages/UsersPage/UsersPage.test.tsx
+++ b/site/src/pages/UsersPage/UsersPage.test.tsx
@@ -272,6 +272,26 @@ describe("Users Page", () => {
expect(API.updateUserRoles).toBeCalledTimes(1)
expect(API.updateUserRoles).toBeCalledWith([...currentRoles, MockAuditorRole.name], MockUser.id)
})
+ it("shows an error from the backend", async () => {
+ render(
+ <>
+
+
+ >,
+ )
+
+ server.use(
+ rest.put(`/api/v2/users/${MockUser.id}/roles`, (req, res, ctx) => {
+ return res(ctx.status(401), ctx.json({ message: "message from the backend" }))
+ }),
+ )
+
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ await updateUserRole(() => {}, MockAuditorRole)
+
+ // Check if the error message is displayed
+ await screen.findByText("message from the backend")
+ })
})
})
})
diff --git a/site/src/xServices/users/usersXService.ts b/site/src/xServices/users/usersXService.ts
index c21219ae6e1be..7566f17ed4623 100644
--- a/site/src/xServices/users/usersXService.ts
+++ b/site/src/xServices/users/usersXService.ts
@@ -1,6 +1,6 @@
import { assign, createMachine } from "xstate"
import * as API from "../../api/api"
-import { ApiError, FieldErrors, isApiError, mapApiErrorToFieldErrors } from "../../api/errors"
+import { ApiError, FieldErrors, getErrorMessage, isApiError, mapApiErrorToFieldErrors } from "../../api/errors"
import * as TypesGen from "../../api/typesGenerated"
import { displayError, displaySuccess } from "../../components/GlobalSnackbar/utils"
import { generateRandomString } from "../../util/random"
@@ -292,17 +292,20 @@ export const usersMachine = createMachine(
displaySuspendSuccess: () => {
displaySuccess(Language.suspendUserSuccess)
},
- displaySuspendedErrorMessage: () => {
- displayError(Language.suspendUserError)
+ displaySuspendedErrorMessage: (context) => {
+ const message = getErrorMessage(context.suspendUserError, Language.suspendUserError)
+ displayError(message)
},
displayResetPasswordSuccess: () => {
displaySuccess(Language.resetUserPasswordSuccess)
},
- displayResetPasswordErrorMessage: () => {
- displayError(Language.resetUserPasswordError)
+ displayResetPasswordErrorMessage: (context) => {
+ const message = getErrorMessage(context.resetUserPasswordError, Language.resetUserPasswordError)
+ displayError(message)
},
- displayUpdateRolesErrorMessage: () => {
- displayError(Language.updateUserRolesError)
+ displayUpdateRolesErrorMessage: (context) => {
+ const message = getErrorMessage(context.updateUserRolesError, Language.updateUserRolesError)
+ displayError(message)
},
generateRandomPassword: assign({
newUserPassword: (_) => generateRandomString(12),
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy