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),