fix: [FL-195][创建用户报错] 为用户服务事务添加异常处理和回滚机制

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
chengkai3
2026-06-18 12:26:58 +08:00
parent 172e124d4d
commit 80cf981fdb
+87 -66
View File
@@ -114,20 +114,24 @@ def create_user(
status="ENABLED", status="ENABLED",
) )
db.add(user) try:
db.flush() db.add(user)
_assign_legacy_roles(db, user_id, []) db.flush()
write_audit_log( _assign_legacy_roles(db, user_id, [])
db, write_audit_log(
action="user.create", db,
actor_user_id=actor_user_id, action="user.create",
detail=compose_audit_detail( actor_user_id=actor_user_id,
f"target_user_id={user.id}", detail=compose_audit_detail(
f"target_username={user.username}", f"target_user_id={user.id}",
f"target_status={user.status}", f"target_username={user.username}",
), f"target_status={user.status}",
) ),
db.commit() )
db.commit()
except SQLAlchemyError:
db.rollback()
return None
created = get_user_by_id(db, user_id) created = get_user_by_id(db, user_id)
if created: if created:
@@ -150,18 +154,22 @@ def delete_user(db: Session, user_id: str, *, actor_user_id: str | None) -> bool
return False return False
target_username = user.username target_username = user.username
revoke_active_sessions_for_user(db, user_id) try:
write_audit_log( revoke_active_sessions_for_user(db, user_id)
db, write_audit_log(
action="user.delete", db,
actor_user_id=actor_user_id, action="user.delete",
detail=compose_audit_detail( actor_user_id=actor_user_id,
f"target_user_id={user_id}", detail=compose_audit_detail(
f"target_username={target_username}", f"target_user_id={user_id}",
), f"target_username={target_username}",
) ),
db.delete(user) )
db.commit() db.delete(user)
db.commit()
except SQLAlchemyError:
db.rollback()
return False
_fire_and_forget( _fire_and_forget(
publish_topic( publish_topic(
@@ -186,20 +194,24 @@ def reset_user_password(
if not user: if not user:
return None return None
user.password_hash = hash_password(payload.new_password) try:
revoke_active_sessions_for_user(db, user_id) user.password_hash = hash_password(payload.new_password)
write_audit_log( revoke_active_sessions_for_user(db, user_id)
db, write_audit_log(
action="user.password.reset", db,
actor_user_id=actor_user_id, action="user.password.reset",
detail=compose_audit_detail( actor_user_id=actor_user_id,
f"target_user_id={user.id}", detail=compose_audit_detail(
f"target_username={user.username}", f"target_user_id={user.id}",
"password_updated=true", f"target_username={user.username}",
"sessions_revoked=true", "password_updated=true",
), "sessions_revoked=true",
) ),
db.commit() )
db.commit()
except SQLAlchemyError:
db.rollback()
return None
updated = get_user_by_id(db, user_id) updated = get_user_by_id(db, user_id)
if updated: if updated:
@@ -276,22 +288,27 @@ def update_user(
if not changed_fields: if not changed_fields:
return serialize_user(user) return serialize_user(user)
write_audit_log( try:
db, write_audit_log(
action="user.update", db,
actor_user_id=actor_user_id, action="user.update",
detail=compose_audit_detail( actor_user_id=actor_user_id,
f"target_user_id={user.id}", detail=compose_audit_detail(
f"target_username={user.username}", f"target_user_id={user.id}",
describe_changed_fields(changed_fields), f"target_username={user.username}",
( describe_changed_fields(changed_fields),
f"status_transition={previous_status}->{user.status}" (
if status_changed f"status_transition={previous_status}->{user.status}"
else None if status_changed
else None
),
), ),
), )
) db.commit()
db.commit() except SQLAlchemyError:
db.rollback()
return None
updated = get_user_by_id(db, user_id) updated = get_user_by_id(db, user_id)
if updated: if updated:
queue_user_auth_refresh(updated, status_changed=status_changed) queue_user_auth_refresh(updated, status_changed=status_changed)
@@ -339,17 +356,21 @@ def set_user_roles(
updated = get_user_by_id(db, user_id) updated = get_user_by_id(db, user_id)
if updated: if updated:
authz = get_user_authorization(db, updated.id) authz = get_user_authorization(db, updated.id)
write_audit_log( try:
db, write_audit_log(
action="user.roles.replace", db,
actor_user_id=actor_user_id, action="user.roles.replace",
detail=compose_audit_detail( actor_user_id=actor_user_id,
f"target_user_id={updated.id}", detail=compose_audit_detail(
f"target_username={updated.username}", f"target_user_id={updated.id}",
f"role_codes={summarize_values(sorted(authz.role_codes))}", f"target_username={updated.username}",
), f"role_codes={summarize_values(sorted(authz.role_codes))}",
) ),
db.commit() )
db.commit()
except SQLAlchemyError:
db.rollback()
return None
queue_user_auth_refresh(updated) queue_user_auth_refresh(updated)
_fire_and_forget( _fire_and_forget(
publish_topic( publish_topic(