Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/hungry-crabs-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@wso2is/admin.agents.v1": patch
"@wso2is/i18n": patch
Comment thread
pavinduLakshan marked this conversation as resolved.
Comment thread
pavinduLakshan marked this conversation as resolved.
"@wso2is/console": patch
---

Show a specific error message when agent creation fails because the organization's application limit has been reached, instead of the generic "Something went wrong" alert.
33 changes: 25 additions & 8 deletions features/admin.agents.v1/components/wizards/add-agent-wizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { AppState } from "@wso2is/admin.core.v1/store";
import { AlertLevels, IdentifiableComponentInterface } from "@wso2is/core/models";
import { addAlert } from "@wso2is/core/store";
import { URLUtils } from "@wso2is/core/utils";
import { AxiosError } from "axios";
import {
CheckboxFieldAdapter,
CheckboxGroupFieldAdapter,
Expand All @@ -44,6 +45,7 @@ import { useDispatch, useSelector } from "react-redux";
import { Dispatch } from "redux";
import { Divider, Grid, Icon, Message } from "semantic-ui-react";
import { addAgent, updateAgentApplicationConfiguration } from "../../api/agents";
import { AGENT_APP_LIMIT_REACHED_SCIM_TYPE } from "../../constants/agents";
import { AgentScimSchema, AgentType } from "../../models/agents";
import "./add-agent-wizard.scss";

Expand Down Expand Up @@ -168,18 +170,33 @@ const AddAgentWizard: FunctionComponent<AddAgentWizardPropsInterface> = (
setCreationResult(result);
setIsShowingSuccessScreen(true);
setIsSubmitting(false);
} catch (_err: unknown) {
} catch (error: unknown) {
// On error, stay on form with the user's values.
setIsShowingSuccessScreen(false);
setCreationResult(null);
setSubmittedValues(null);
dispatch(
addAlert({
description: t("agents:wizard.alerts.error.description"),
level: AlertLevels.ERROR,
message: t("agents:wizard.alerts.error.message")
})
);

const errorResponse: AxiosError<{ scimType?: string }>["response"] =
(error as AxiosError<{ scimType?: string }>)?.response;

if (errorResponse?.status === 403
&& errorResponse?.data?.scimType === AGENT_APP_LIMIT_REACHED_SCIM_TYPE) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason why we can't check for the error code instead of checking the scimType, as we have done in other places? checking the scimType for this kind of error looks odd, IMO.

&& error?.response?.data?.code
=== RoleConstants.ERROR_CREATE_LIMIT_REACHED.getErrorCode()) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent creation goes through the SCIM2 API (POST /scim2/Agents), not an internal server REST API. SCIM error responses only carry status, scimType, and detail — there is no code attribute in the payload, so an error-code check isn't possible here. scimType is SCIM's machine-readable error slot.

The role wizard example calls the Roles REST API, which does return a code field — a different API contract. For SCIM flows, this follows the existing precedent in this repo: the add-user wizard checks scimType === "userLimitReached" for the user creation limit (features/admin.users.v1/components/wizard/add-user-wizard.tsx). The backend counterpart (wso2-extensions/identity-inbound-provisioning-scim2#799) mirrors that existing userLimitReached mapping with applicationLimitReached.

dispatch(
addAlert({
description: t("agents:wizard.alerts.limitReached.description"),
level: AlertLevels.ERROR,
message: t("agents:wizard.alerts.limitReached.message")
})
);
} else {
dispatch(
addAlert({
description: t("agents:wizard.alerts.error.description"),
level: AlertLevels.ERROR,
message: t("agents:wizard.alerts.error.message")
})
);
}
setIsSubmitting(false);
}
};
Expand Down
6 changes: 6 additions & 0 deletions features/admin.agents.v1/constants/agents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@

export const AGENT_SHARING_ERROR: string = "AGENT_SHARING_ERROR";

/**
* SCIM `scimType` value returned when agent creation fails because the
* organization has reached its allowed application limit.
*/
export const AGENT_APP_LIMIT_REACHED_SCIM_TYPE: string = "applicationLimitReached";

export const AGENT_FEATURE_DICTIONARY: Map<string, string> = new Map()
.set("AGENT_GROUPS", "agents.groups")
.set("AGENT_SHARED_ACCESS", "agents.sharedAccess")
Expand Down
4 changes: 4 additions & 0 deletions modules/i18n/src/models/namespaces/agents-ns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ export interface AgentsNS {
message: string;
description: string;
};
limitReached: {
message: string;
description: string;
};
clientIdFetchFailed: {
message: string;
description: string;
Expand Down
4 changes: 4 additions & 0 deletions modules/i18n/src/translations/en-US/portals/agents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ export const agents: AgentsNS = {
error: {
description: "Creating agent failed",
message: "Something went wrong"
},
limitReached: {
description: "Agent application creation failed. Maximum application limit reached.",
message: "Application limit reached"
}
},
buttons: {
Expand Down
Loading