Skip to content

Commit a0a6c2e

Browse files
authored
🐛 Bugfix: create tenant failed
🐛 Bugfix: create tenant failed
2 parents e5d2dbb + ce5d390 commit a0a6c2e

File tree

7 files changed

+229
-43
lines changed

7 files changed

+229
-43
lines changed

backend/services/tenant_service.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,32 @@ def _ensure_tenant_name_config(tenant_id: str) -> bool:
8383
return success
8484

8585

86+
def check_tenant_name_exists(tenant_name: str, exclude_tenant_id: Optional[str] = None) -> bool:
87+
"""
88+
Check if a tenant with the given name already exists
89+
90+
Args:
91+
tenant_name (str): Tenant name to check
92+
exclude_tenant_id (Optional[str]): Tenant ID to exclude from check (for rename operations)
93+
94+
Returns:
95+
bool: True if tenant name already exists, False otherwise
96+
"""
97+
all_tenant_ids = get_all_tenant_ids()
98+
99+
for tid in all_tenant_ids:
100+
# Skip if this is the tenant being updated
101+
if exclude_tenant_id and tid == exclude_tenant_id:
102+
continue
103+
104+
# Check if this tenant has the given name
105+
name_config = get_single_config_info(tid, TENANT_NAME)
106+
if name_config and name_config.get("config_value") == tenant_name:
107+
return True
108+
109+
return False
110+
111+
86112
def get_all_tenants() -> List[Dict[str, Any]]:
87113
"""
88114
Get all tenants
@@ -122,24 +148,19 @@ def create_tenant(tenant_name: str, created_by: Optional[str] = None) -> Dict[st
122148
Dict[str, Any]: Created tenant information
123149
124150
Raises:
125-
ValidationError: When tenant creation fails
151+
ValidationError: When tenant creation fails or tenant name already exists
126152
"""
127153
# Generate a random UUID for tenant_id
128154
tenant_id = str(uuid.uuid4())
129155

130-
# Check if tenant already exists (extremely unlikely with UUID, but good practice)
131-
try:
132-
existing_tenant = get_tenant_info(tenant_id)
133-
if existing_tenant:
134-
raise ValidationError(f"Tenant {tenant_id} already exists")
135-
except NotFoundException:
136-
# Tenant doesn't exist, which is what we want
137-
pass
138-
139156
# Validate tenant name
140157
if not tenant_name or not tenant_name.strip():
141158
raise ValidationError("Tenant name cannot be empty")
142159

160+
# Check if tenant name already exists
161+
if check_tenant_name_exists(tenant_name.strip()):
162+
raise ValidationError(f"Tenant with name '{tenant_name.strip()}' already exists")
163+
143164
try:
144165
# Create default group first
145166
default_group_id = _create_default_group_for_tenant(tenant_id, created_by)
@@ -215,6 +236,10 @@ def update_tenant_info(tenant_id: str, tenant_name: str, updated_by: Optional[st
215236
if not tenant_name or not tenant_name.strip():
216237
raise ValidationError("Tenant name cannot be empty")
217238

239+
# Check if tenant name already exists (exclude current tenant)
240+
if check_tenant_name_exists(tenant_name.strip(), exclude_tenant_id=tenant_id):
241+
raise ValidationError(f"Tenant with name '{tenant_name.strip()}' already exists")
242+
218243
# Check if tenant name config exists
219244
name_config = get_single_config_info(tenant_id, TENANT_NAME)
220245
if not name_config:

frontend/app/[locale]/tenant-resources/components/UserManageComp.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,20 @@ function TenantList({
103103
message.success(t("tenantResources.tenants.created"));
104104
}
105105
setModalVisible(false);
106-
} catch (err) {
107-
message.error(t("tenantResources.tenantOperationFailed"));
106+
} catch (err: any) {
107+
const errorMessage = err?.response?.data?.message || err?.message || "";
108+
const nameConflictMatch = errorMessage.match(/Tenant with name '(.*)' already exists/i);
109+
110+
if (nameConflictMatch && nameConflictMatch[1]) {
111+
// Extract the duplicate name and show translated error
112+
message.error(t("tenantResources.tenants.nameExists", { name: nameConflictMatch[1] }));
113+
} else if (errorMessage.includes("Tenant name cannot be empty")) {
114+
// Handle empty name error
115+
message.error(t("tenantResources.tenants.nameRequired"));
116+
} else {
117+
// Show generic error for other cases
118+
message.error(t("tenantResources.tenantOperationFailed"));
119+
}
108120
}
109121
};
110122

frontend/app/[locale]/tenant-resources/components/resources/ModelList.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@ export default function ModelList({ tenantId }: { tenantId: string | null }) {
6868
const handleDelete = async (modelId: string, provider?: string) => {
6969
try {
7070
await modelService.deleteCustomModel(modelId, provider);
71-
message.success("Model deleted");
71+
message.success(t("tenantResources.models.deleteSuccess"));
7272
refetch();
7373
} catch (error: any) {
7474
if (error.response?.data?.message) {
7575
message.error(error.response.data.message);
7676
} else {
77-
message.error("Delete failed");
77+
message.error(t("tenantResources.models.deleteFailed"));
7878
}
7979
}
8080
};
@@ -160,7 +160,7 @@ export default function ModelList({ tenantId }: { tenantId: string | null }) {
160160
</Tooltip>
161161
<Popconfirm
162162
title={t("tenantResources.models.confirmDelete")}
163-
description="This action cannot be undone."
163+
description={t("common.cannotBeUndone")}
164164
onConfirm={() => handleDelete(record.displayName, record.source)}
165165
>
166166
<Tooltip title={t("tenantResources.models.deleteModel")}>

frontend/hooks/auth/useAuthenticationState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export function useAuthenticationState(): AuthenticationStateReturn {
147147
setIsAuthenticated(true);
148148

149149
setTimeout(() => {
150-
message.success(t("auth.registrationSuccess"));
150+
message.success(t("auth.registerSuccessAutoLogin"));
151151

152152
// Emit register success event to close register modal
153153
authEventUtils.emitRegisterSuccess();

frontend/public/locales/en/common.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,10 @@
13091309
"tenantResources.models.type.vlm": "Visual Language Model",
13101310

13111311
"tenantResources.models.confirmDelete": "Delete model?",
1312+
"tenantResources.models.editModel": "Edit Model",
1313+
"tenantResources.models.deleteModel": "Delete Model",
1314+
"tenantResources.models.deleteSuccess": "Model deleted",
1315+
"tenantResources.models.deleteFailed": "Delete failed",
13121316
"tenantResources.models.enterDescription": "Enter model description",
13131317
"tenantResources.models.enterName": "Enter model name",
13141318

@@ -1322,6 +1326,8 @@
13221326
"tenantResources.tenants.tenants": "Tenants",
13231327
"tenantResources.tenants.unnamed": "Unnamed Tenant",
13241328
"tenantResources.tenants.updated": "Tenant updated",
1329+
"tenantResources.tenants.nameExists": "Tenant name '{{name}}' already exists, please use a different name",
1330+
"tenantResources.tenants.nameRequired": "Please enter a tenant name",
13251331

13261332
"tenantResources.users.confirmDelete": "Delete user \"{{name}}\"?",
13271333
"tenantResources.users.deleteUser": "Delete User",

frontend/public/locales/zh/common.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,10 @@
13101310
"tenantResources.models.type.vlm": "视觉语言模型",
13111311

13121312
"tenantResources.models.confirmDelete": "删除模型?",
1313+
"tenantResources.models.editModel": "编辑模型",
1314+
"tenantResources.models.deleteModel": "删除模型",
1315+
"tenantResources.models.deleteSuccess": "模型已删除",
1316+
"tenantResources.models.deleteFailed": "删除模型失败",
13131317
"tenantResources.models.enterDescription": "输入模型描述",
13141318
"tenantResources.models.enterName": "输入模型名称",
13151319

@@ -1323,6 +1327,8 @@
13231327
"tenantResources.tenants.tenants": "租户",
13241328
"tenantResources.tenants.unnamed": "未命名租户",
13251329
"tenantResources.tenants.updated": "租户已更新",
1330+
"tenantResources.tenants.nameExists": "租户名称 '{{name}}' 已存在,请使用其他名称",
1331+
"tenantResources.tenants.nameRequired": "请输入租户名称",
13261332

13271333
"tenantResources.users.confirmDelete": "删除用户\"{{name}}\"",
13281334
"tenantResources.users.deleteUser": "删除用户",

0 commit comments

Comments
 (0)