Skip to content

Commit 178da27

Browse files
committed
feat(authz): implement error handling for role assignment with localized messages
1 parent d2ba639 commit 178da27

4 files changed

Lines changed: 51 additions & 4 deletions

File tree

src/authz-module/role-assignation-wizard/AssignRoleWizard.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { libraryRolesMetadata } from '../roles-permissions/library/constants';
1414
import { courseRolesMetadata } from '../roles-permissions/course/constants';
1515
import { useValidateUsers, useAssignTeamMembersRole } from '../data/hooks';
1616
import messages from './messages';
17+
import { formatRoleAssignmentError } from './utils';
1718

1819
const allRolesMetadata = [...courseRolesMetadata, ...libraryRolesMetadata];
1920

@@ -119,10 +120,8 @@ const AssignRoleWizard = ({ onClose, initialUsers = '', roles = allRolesMetadata
119120
});
120121

121122
if (result.errors?.length > 0) {
122-
const msg = result.errors
123-
.map((e) => `${e.userIdentifier} (${e.scope}): ${e.error}`)
124-
.join(', ');
125-
showErrorToast(new Error(msg), handleSave);
123+
const lines = result.errors.map((e) => formatRoleAssignmentError(intl, e));
124+
showToast({ message: lines.join(' · '), type: 'error' });
126125
} else {
127126
showToast({
128127
message: intl.formatMessage(messages['wizard.save.success']),
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const ROLE_ASSIGNMENT_ERRORS = {
2+
USER_ALREADY_HAS_ROLE: 'user_already_has_role',
3+
USER_NOT_FOUND: 'user_not_found',
4+
ROLE_ASSIGNMENT_ERROR: 'role_assignment_error',
5+
} as const;

src/authz-module/role-assignation-wizard/messages.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,26 @@ const messages = defineMessages({
6868
defaultMessage: 'Role assigned successfully.',
6969
description: 'Toast message shown when a role is successfully assigned',
7070
},
71+
'wizard.save.error.user_already_has_role': {
72+
id: 'wizard.save.error.user_already_has_role',
73+
defaultMessage: '{userIdentifier} already has this role in {scope}',
74+
description: 'Error shown in the toast when the user already holds the role in the selected scope',
75+
},
76+
'wizard.save.error.user_not_found': {
77+
id: 'wizard.save.error.user_not_found',
78+
defaultMessage: 'User "{userIdentifier}" was not found',
79+
description: 'Error shown in the toast when the username or email does not match any account',
80+
},
81+
'wizard.save.error.role_assignment_error': {
82+
id: 'wizard.save.error.role_assignment_error',
83+
defaultMessage: 'Could not assign role to {userIdentifier} in {scope}',
84+
description: 'Error shown in the toast when an unexpected error occurs during role assignment',
85+
},
86+
'wizard.save.error.default': {
87+
id: 'wizard.save.error.default',
88+
defaultMessage: '{userIdentifier} ({scope}): {error}',
89+
description: 'Fallback error line shown in the toast for unknown role-assignment error codes',
90+
},
7191

7292
// DefineApplicationScopeStep — filter bar
7393
'wizard.step2.search.placeholder': {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { IntlShape } from '@edx/frontend-platform/i18n';
2+
import { PutAssignTeamMembersRoleResponse } from '@src/authz-module/data/api';
3+
import { ROLE_ASSIGNMENT_ERRORS } from './constants';
4+
import messages from './messages';
5+
6+
type RoleAssignmentError = PutAssignTeamMembersRoleResponse['errors'][number];
7+
8+
export const formatRoleAssignmentError = (
9+
intl: IntlShape,
10+
e: RoleAssignmentError,
11+
): string => {
12+
const params = { userIdentifier: e.userIdentifier, scope: e.scope };
13+
if (e.error === ROLE_ASSIGNMENT_ERRORS.USER_ALREADY_HAS_ROLE) {
14+
return intl.formatMessage(messages['wizard.save.error.user_already_has_role'], params);
15+
}
16+
if (e.error === ROLE_ASSIGNMENT_ERRORS.USER_NOT_FOUND) {
17+
return intl.formatMessage(messages['wizard.save.error.user_not_found'], params);
18+
}
19+
if (e.error === ROLE_ASSIGNMENT_ERRORS.ROLE_ASSIGNMENT_ERROR) {
20+
return intl.formatMessage(messages['wizard.save.error.role_assignment_error'], params);
21+
}
22+
return intl.formatMessage(messages['wizard.save.error.default'], { ...params, error: e.error });
23+
};

0 commit comments

Comments
 (0)