refactor(logging): switch to parameterized logging for improved performance and clarity

- Replaced f-strings with parameterized logging calls across routes, services, and repositories to optimize log message evaluation.
- Improved exception handling by using `logger.exception` where appropriate for automatic traceback logging.
This commit is contained in:
2026-03-01 13:38:15 +01:00
parent 57e969ed67
commit 0553a1fc53
24 changed files with 375 additions and 319 deletions

View File

@@ -243,7 +243,7 @@ async def admin_get_stats(
# 4. User Status - Active vs Inactive
logger.info(
f"User status counts - Active: {active_count}, Inactive: {inactive_count}"
"User status counts - Active: %s, Inactive: %s", active_count, inactive_count
)
user_status = [
@@ -312,7 +312,7 @@ async def admin_list_users(
return PaginatedResponse(data=users, pagination=pagination_meta)
except Exception as e:
logger.error(f"Error listing users (admin): {e!s}", exc_info=True)
logger.exception("Error listing users (admin): %s", e)
raise
@@ -336,13 +336,13 @@ async def admin_create_user(
"""
try:
user = await user_service.create_user(db, user_in)
logger.info(f"Admin {admin.email} created user {user.email}")
logger.info("Admin %s created user %s", admin.email, user.email)
return user
except DuplicateEntryError as e:
logger.warning(f"Failed to create user: {e!s}")
logger.warning("Failed to create user: %s", e)
raise DuplicateError(message=str(e), error_code=ErrorCode.USER_ALREADY_EXISTS)
except Exception as e:
logger.error(f"Error creating user (admin): {e!s}", exc_info=True)
logger.exception("Error creating user (admin): %s", e)
raise
@@ -380,11 +380,11 @@ async def admin_update_user(
try:
user = await user_service.get_user(db, str(user_id))
updated_user = await user_service.update_user(db, user=user, obj_in=user_in)
logger.info(f"Admin {admin.email} updated user {updated_user.email}")
logger.info("Admin %s updated user %s", admin.email, updated_user.email)
return updated_user
except Exception as e:
logger.error(f"Error updating user (admin): {e!s}", exc_info=True)
logger.exception("Error updating user (admin): %s", e)
raise
@@ -413,14 +413,14 @@ async def admin_delete_user(
)
await user_service.soft_delete_user(db, str(user_id))
logger.info(f"Admin {admin.email} deleted user {user.email}")
logger.info("Admin %s deleted user %s", admin.email, user.email)
return MessageResponse(
success=True, message=f"User {user.email} has been deleted"
)
except Exception as e:
logger.error(f"Error deleting user (admin): {e!s}", exc_info=True)
logger.exception("Error deleting user (admin): %s", e)
raise
@@ -440,14 +440,14 @@ async def admin_activate_user(
try:
user = await user_service.get_user(db, str(user_id))
await user_service.update_user(db, user=user, obj_in={"is_active": True})
logger.info(f"Admin {admin.email} activated user {user.email}")
logger.info("Admin %s activated user %s", admin.email, user.email)
return MessageResponse(
success=True, message=f"User {user.email} has been activated"
)
except Exception as e:
logger.error(f"Error activating user (admin): {e!s}", exc_info=True)
logger.exception("Error activating user (admin): %s", e)
raise
@@ -476,14 +476,14 @@ async def admin_deactivate_user(
)
await user_service.update_user(db, user=user, obj_in={"is_active": False})
logger.info(f"Admin {admin.email} deactivated user {user.email}")
logger.info("Admin %s deactivated user %s", admin.email, user.email)
return MessageResponse(
success=True, message=f"User {user.email} has been deactivated"
)
except Exception as e:
logger.error(f"Error deactivating user (admin): {e!s}", exc_info=True)
logger.exception("Error deactivating user (admin): %s", e)
raise
@@ -528,8 +528,11 @@ async def admin_bulk_user_action(
failed_count = requested_count - affected_count
logger.info(
f"Admin {admin.email} performed bulk {bulk_action.action.value} "
f"on {affected_count} users ({failed_count} skipped/failed)"
"Admin %s performed bulk %s on %s users (%s skipped/failed)",
admin.email,
bulk_action.action.value,
affected_count,
failed_count,
)
return BulkActionResult(
@@ -541,7 +544,7 @@ async def admin_bulk_user_action(
)
except Exception as e: # pragma: no cover
logger.error(f"Error in bulk user action: {e!s}", exc_info=True)
logger.exception("Error in bulk user action: %s", e)
raise
@@ -602,7 +605,7 @@ async def admin_list_organizations(
return PaginatedResponse(data=orgs_with_count, pagination=pagination_meta)
except Exception as e:
logger.error(f"Error listing organizations (admin): {e!s}", exc_info=True)
logger.exception("Error listing organizations (admin): %s", e)
raise
@@ -622,7 +625,7 @@ async def admin_create_organization(
"""Create a new organization."""
try:
org = await organization_service.create_organization(db, obj_in=org_in)
logger.info(f"Admin {admin.email} created organization {org.name}")
logger.info("Admin %s created organization %s", admin.email, org.name)
# Add member count
org_dict = {
@@ -639,10 +642,10 @@ async def admin_create_organization(
return OrganizationResponse(**org_dict)
except DuplicateEntryError as e:
logger.warning(f"Failed to create organization: {e!s}")
logger.warning("Failed to create organization: %s", e)
raise DuplicateError(message=str(e), error_code=ErrorCode.ALREADY_EXISTS)
except Exception as e:
logger.error(f"Error creating organization (admin): {e!s}", exc_info=True)
logger.exception("Error creating organization (admin): %s", e)
raise
@@ -695,7 +698,7 @@ async def admin_update_organization(
updated_org = await organization_service.update_organization(
db, org=org, obj_in=org_in
)
logger.info(f"Admin {admin.email} updated organization {updated_org.name}")
logger.info("Admin %s updated organization %s", admin.email, updated_org.name)
org_dict = {
"id": updated_org.id,
@@ -713,7 +716,7 @@ async def admin_update_organization(
return OrganizationResponse(**org_dict)
except Exception as e:
logger.error(f"Error updating organization (admin): {e!s}", exc_info=True)
logger.exception("Error updating organization (admin): %s", e)
raise
@@ -733,14 +736,14 @@ async def admin_delete_organization(
try:
org = await organization_service.get_organization(db, str(org_id))
await organization_service.remove_organization(db, str(org_id))
logger.info(f"Admin {admin.email} deleted organization {org.name}")
logger.info("Admin %s deleted organization %s", admin.email, org.name)
return MessageResponse(
success=True, message=f"Organization {org.name} has been deleted"
)
except Exception as e:
logger.error(f"Error deleting organization (admin): {e!s}", exc_info=True)
logger.exception("Error deleting organization (admin): %s", e)
raise
@@ -784,9 +787,7 @@ async def admin_list_organization_members(
except NotFoundError:
raise
except Exception as e:
logger.error(
f"Error listing organization members (admin): {e!s}", exc_info=True
)
logger.exception("Error listing organization members (admin): %s", e)
raise
@@ -822,8 +823,11 @@ async def admin_add_organization_member(
)
logger.info(
f"Admin {admin.email} added user {user.email} to organization {org.name} "
f"with role {request.role.value}"
"Admin %s added user %s to organization %s with role %s",
admin.email,
user.email,
org.name,
request.role.value,
)
return MessageResponse(
@@ -831,14 +835,12 @@ async def admin_add_organization_member(
)
except DuplicateEntryError as e:
logger.warning(f"Failed to add user to organization: {e!s}")
logger.warning("Failed to add user to organization: %s", e)
raise DuplicateError(
message=str(e), error_code=ErrorCode.USER_ALREADY_EXISTS, field="user_id"
)
except Exception as e:
logger.error(
f"Error adding member to organization (admin): {e!s}", exc_info=True
)
logger.exception("Error adding member to organization (admin): %s", e)
raise
@@ -871,7 +873,10 @@ async def admin_remove_organization_member(
)
logger.info(
f"Admin {admin.email} removed user {user.email} from organization {org.name}"
"Admin %s removed user %s from organization %s",
admin.email,
user.email,
org.name,
)
return MessageResponse(
@@ -882,9 +887,7 @@ async def admin_remove_organization_member(
except NotFoundError:
raise
except Exception as e: # pragma: no cover
logger.error(
f"Error removing member from organization (admin): {e!s}", exc_info=True
)
logger.exception("Error removing member from organization (admin): %s", e)
raise
@@ -953,7 +956,10 @@ async def admin_list_sessions(
session_responses.append(session_response)
logger.info(
f"Admin {admin.email} listed {len(session_responses)} sessions (total: {total})"
"Admin %s listed %s sessions (total: %s)",
admin.email,
len(session_responses),
total,
)
pagination_meta = create_pagination_meta(
@@ -966,5 +972,5 @@ async def admin_list_sessions(
return PaginatedResponse(data=session_responses, pagination=pagination_meta)
except Exception as e: # pragma: no cover
logger.error(f"Error listing sessions (admin): {e!s}", exc_info=True)
logger.exception("Error listing sessions (admin): %s", e)
raise

View File

@@ -94,14 +94,15 @@ async def _create_login_session(
await session_service.create_session(db, obj_in=session_data)
logger.info(
f"{login_type.capitalize()} successful: {user.email} from {device_info.device_name} "
f"(IP: {device_info.ip_address})"
"%s successful: %s from %s (IP: %s)",
login_type.capitalize(),
user.email,
device_info.device_name,
device_info.ip_address,
)
except Exception as session_err:
# Log but don't fail login if session creation fails
logger.error(
f"Failed to create session for {user.email}: {session_err!s}", exc_info=True
)
logger.exception("Failed to create session for %s: %s", user.email, session_err)
@router.post(
@@ -125,19 +126,19 @@ async def register_user(
return user
except DuplicateError:
# SECURITY: Don't reveal if email exists - generic error message
logger.warning(f"Registration failed: duplicate email {user_data.email}")
logger.warning("Registration failed: duplicate email %s", user_data.email)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Registration failed. Please check your information and try again.",
)
except AuthError as e:
logger.warning(f"Registration failed: {e!s}")
logger.warning("Registration failed: %s", e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Registration failed. Please check your information and try again.",
)
except Exception as e:
logger.error(f"Unexpected error during registration: {e!s}", exc_info=True)
logger.exception("Unexpected error during registration: %s", e)
raise DatabaseError(
message="An unexpected error occurred. Please try again later.",
error_code=ErrorCode.INTERNAL_ERROR,
@@ -165,7 +166,7 @@ async def login(
# Explicitly check for None result and raise correct exception
if user is None:
logger.warning(f"Invalid login attempt for: {login_data.email}")
logger.warning("Invalid login attempt for: %s", login_data.email)
raise AuthError(
message="Invalid email or password",
error_code=ErrorCode.INVALID_CREDENTIALS,
@@ -181,11 +182,11 @@ async def login(
except AuthenticationError as e:
# Handle specific authentication errors like inactive accounts
logger.warning(f"Authentication failed: {e!s}")
logger.warning("Authentication failed: %s", e)
raise AuthError(message=str(e), error_code=ErrorCode.INVALID_CREDENTIALS)
except Exception as e:
# Handle unexpected errors
logger.error(f"Unexpected error during login: {e!s}", exc_info=True)
logger.exception("Unexpected error during login: %s", e)
raise DatabaseError(
message="An unexpected error occurred. Please try again later.",
error_code=ErrorCode.INTERNAL_ERROR,
@@ -227,10 +228,10 @@ async def login_oauth(
# Return full token response with user data
return tokens
except AuthenticationError as e:
logger.warning(f"OAuth authentication failed: {e!s}")
logger.warning("OAuth authentication failed: %s", e)
raise AuthError(message=str(e), error_code=ErrorCode.INVALID_CREDENTIALS)
except Exception as e:
logger.error(f"Unexpected error during OAuth login: {e!s}", exc_info=True)
logger.exception("Unexpected error during OAuth login: %s", e)
raise DatabaseError(
message="An unexpected error occurred. Please try again later.",
error_code=ErrorCode.INTERNAL_ERROR,
@@ -263,7 +264,8 @@ async def refresh_token(
if not session:
logger.warning(
f"Refresh token used for inactive or non-existent session: {refresh_payload.jti}"
"Refresh token used for inactive or non-existent session: %s",
refresh_payload.jti,
)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
@@ -286,9 +288,7 @@ async def refresh_token(
new_expires_at=datetime.fromtimestamp(new_refresh_payload.exp, tz=UTC),
)
except Exception as session_err:
logger.error(
f"Failed to update session {session.id}: {session_err!s}", exc_info=True
)
logger.exception("Failed to update session %s: %s", session.id, session_err)
# Continue anyway - tokens are already issued
return tokens
@@ -311,7 +311,7 @@ async def refresh_token(
# Re-raise HTTP exceptions (like session revoked)
raise
except Exception as e:
logger.error(f"Unexpected error during token refresh: {e!s}")
logger.error("Unexpected error during token refresh: %s", e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="An unexpected error occurred. Please try again later.",
@@ -358,11 +358,12 @@ async def request_password_reset(
await email_service.send_password_reset_email(
to_email=user.email, reset_token=reset_token, user_name=user.first_name
)
logger.info(f"Password reset requested for {user.email}")
logger.info("Password reset requested for %s", user.email)
else:
# Log attempt but don't reveal if email exists
logger.warning(
f"Password reset requested for non-existent or inactive email: {reset_request.email}"
"Password reset requested for non-existent or inactive email: %s",
reset_request.email,
)
# Always return success to prevent email enumeration
@@ -371,7 +372,7 @@ async def request_password_reset(
message="If your email is registered, you will receive a password reset link shortly",
)
except Exception as e:
logger.error(f"Error processing password reset request: {e!s}", exc_info=True)
logger.exception("Error processing password reset request: %s", e)
# Still return success to prevent information leakage
return MessageResponse(
success=True,
@@ -432,12 +433,14 @@ async def confirm_password_reset(
db, user_id=str(user.id)
)
logger.info(
f"Password reset successful for {user.email}, invalidated {deactivated_count} sessions"
"Password reset successful for %s, invalidated %s sessions",
user.email,
deactivated_count,
)
except Exception as session_error:
# Log but don't fail password reset if session invalidation fails
logger.error(
f"Failed to invalidate sessions after password reset: {session_error!s}"
"Failed to invalidate sessions after password reset: %s", session_error
)
return MessageResponse(
@@ -448,7 +451,7 @@ async def confirm_password_reset(
except HTTPException:
raise
except Exception as e:
logger.error(f"Error confirming password reset: {e!s}", exc_info=True)
logger.exception("Error confirming password reset: %s", e)
await db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@@ -498,7 +501,7 @@ async def logout(
)
except (TokenExpiredError, TokenInvalidError) as e:
# Even if token is expired/invalid, try to deactivate session
logger.warning(f"Logout with invalid/expired token: {e!s}")
logger.warning("Logout with invalid/expired token: %s", e)
# Don't fail - return success anyway
return MessageResponse(success=True, message="Logged out successfully")
@@ -509,8 +512,10 @@ async def logout(
# Verify session belongs to current user (security check)
if str(session.user_id) != str(current_user.id):
logger.warning(
f"User {current_user.id} attempted to logout session {session.id} "
f"belonging to user {session.user_id}"
"User %s attempted to logout session %s belonging to user %s",
current_user.id,
session.id,
session.user_id,
)
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
@@ -521,14 +526,17 @@ async def logout(
await session_service.deactivate(db, session_id=str(session.id))
logger.info(
f"User {current_user.id} logged out from {session.device_name} "
f"(session {session.id})"
"User %s logged out from %s (session %s)",
current_user.id,
session.device_name,
session.id,
)
else:
# Session not found - maybe already deleted or never existed
# Return success anyway (idempotent)
logger.info(
f"Logout requested for non-existent session (JTI: {refresh_payload.jti})"
"Logout requested for non-existent session (JTI: %s)",
refresh_payload.jti,
)
return MessageResponse(success=True, message="Logged out successfully")
@@ -536,9 +544,7 @@ async def logout(
except HTTPException:
raise
except Exception as e:
logger.error(
f"Error during logout for user {current_user.id}: {e!s}", exc_info=True
)
logger.exception("Error during logout for user %s: %s", current_user.id, e)
# Don't expose error details
return MessageResponse(success=True, message="Logged out successfully")
@@ -581,7 +587,7 @@ async def logout_all(
)
logger.info(
f"User {current_user.id} logged out from all devices ({count} sessions)"
"User %s logged out from all devices (%s sessions)", current_user.id, count
)
return MessageResponse(
@@ -590,9 +596,7 @@ async def logout_all(
)
except Exception as e:
logger.error(
f"Error during logout-all for user {current_user.id}: {e!s}", exc_info=True
)
logger.exception("Error during logout-all for user %s: %s", current_user.id, e)
await db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,

View File

@@ -84,14 +84,16 @@ async def _create_oauth_login_session(
await session_service.create_session(db, obj_in=session_data)
logger.info(
f"OAuth login successful: {user.email} via {provider} "
f"from {device_info.device_name} (IP: {device_info.ip_address})"
"OAuth login successful: %s via %s from %s (IP: %s)",
user.email,
provider,
device_info.device_name,
device_info.ip_address,
)
except Exception as session_err:
# Log but don't fail login if session creation fails
logger.error(
f"Failed to create session for OAuth login {user.email}: {session_err!s}",
exc_info=True,
logger.exception(
"Failed to create session for OAuth login %s: %s", user.email, session_err
)
@@ -176,13 +178,13 @@ async def get_authorization_url(
}
except AuthError as e:
logger.warning(f"OAuth authorization failed: {e!s}")
logger.warning("OAuth authorization failed: %s", e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e),
)
except Exception as e:
logger.error(f"OAuth authorization error: {e!s}", exc_info=True)
logger.exception("OAuth authorization error: %s", e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to create authorization URL",
@@ -250,13 +252,13 @@ async def handle_callback(
return result
except AuthError as e:
logger.warning(f"OAuth callback failed: {e!s}")
logger.warning("OAuth callback failed: %s", e)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=str(e),
)
except Exception as e:
logger.error(f"OAuth callback error: {e!s}", exc_info=True)
logger.exception("OAuth callback error: %s", e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="OAuth authentication failed",
@@ -337,13 +339,13 @@ async def unlink_account(
)
except AuthError as e:
logger.warning(f"OAuth unlink failed for {current_user.email}: {e!s}")
logger.warning("OAuth unlink failed for %s: %s", current_user.email, e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e),
)
except Exception as e:
logger.error(f"OAuth unlink error: {e!s}", exc_info=True)
logger.exception("OAuth unlink error: %s", e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to unlink OAuth account",
@@ -419,13 +421,13 @@ async def start_link(
}
except AuthError as e:
logger.warning(f"OAuth link authorization failed: {e!s}")
logger.warning("OAuth link authorization failed: %s", e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e),
)
except Exception as e:
logger.error(f"OAuth link error: {e!s}", exc_info=True)
logger.exception("OAuth link error: %s", e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to create authorization URL",

View File

@@ -452,7 +452,7 @@ async def token(
except Exception as e:
# Log malformed Basic auth for security monitoring
logger.warning(
f"Malformed Basic auth header in token request: {type(e).__name__}"
"Malformed Basic auth header in token request: %s", type(e).__name__
)
# Fall back to form body
@@ -563,7 +563,8 @@ async def revoke(
except Exception as e:
# Log malformed Basic auth for security monitoring
logger.warning(
f"Malformed Basic auth header in revoke request: {type(e).__name__}"
"Malformed Basic auth header in revoke request: %s",
type(e).__name__,
)
# Fall back to form body
@@ -585,7 +586,7 @@ async def revoke(
)
except Exception as e:
# Log but don't expose errors per RFC 7009
logger.warning(f"Token revocation error: {e}")
logger.warning("Token revocation error: %s", e)
# Always return 200 OK per RFC 7009
return {"status": "ok"}
@@ -634,7 +635,8 @@ async def introspect(
except Exception as e:
# Log malformed Basic auth for security monitoring
logger.warning(
f"Malformed Basic auth header in introspect request: {type(e).__name__}"
"Malformed Basic auth header in introspect request: %s",
type(e).__name__,
)
# Fall back to form body
@@ -654,7 +656,7 @@ async def introspect(
headers={"WWW-Authenticate": "Basic"},
)
except Exception as e:
logger.warning(f"Token introspection error: {e}")
logger.warning("Token introspection error: %s", e)
return OAuthTokenIntrospectionResponse(active=False) # pyright: ignore[reportCallIssue]

View File

@@ -77,7 +77,7 @@ async def get_my_organizations(
return orgs_with_data
except Exception as e:
logger.error(f"Error getting user organizations: {e!s}", exc_info=True)
logger.exception("Error getting user organizations: %s", e)
raise
@@ -116,7 +116,7 @@ async def get_organization(
return OrganizationResponse(**org_dict)
except Exception as e:
logger.error(f"Error getting organization: {e!s}", exc_info=True)
logger.exception("Error getting organization: %s", e)
raise
@@ -160,7 +160,7 @@ async def get_organization_members(
return PaginatedResponse(data=member_responses, pagination=pagination_meta)
except Exception as e:
logger.error(f"Error getting organization members: {e!s}", exc_info=True)
logger.exception("Error getting organization members: %s", e)
raise
@@ -188,7 +188,7 @@ async def update_organization(
db, org=org, obj_in=org_in
)
logger.info(
f"User {current_user.email} updated organization {updated_org.name}"
"User %s updated organization %s", current_user.email, updated_org.name
)
org_dict = {
@@ -207,5 +207,5 @@ async def update_organization(
return OrganizationResponse(**org_dict)
except Exception as e:
logger.error(f"Error updating organization: {e!s}", exc_info=True)
logger.exception("Error updating organization: %s", e)
raise

View File

@@ -74,9 +74,7 @@ async def list_my_sessions(
# For now, we'll mark current based on most recent activity
except Exception as e:
# Optional token parsing - silently ignore failures
logger.debug(
f"Failed to decode access token for session marking: {e!s}"
)
logger.debug("Failed to decode access token for session marking: %s", e)
# Convert to response format
session_responses = []
@@ -98,7 +96,7 @@ async def list_my_sessions(
session_responses.append(session_response)
logger.info(
f"User {current_user.id} listed {len(session_responses)} active sessions"
"User %s listed %s active sessions", current_user.id, len(session_responses)
)
return SessionListResponse(
@@ -106,9 +104,7 @@ async def list_my_sessions(
)
except Exception as e:
logger.error(
f"Error listing sessions for user {current_user.id}: {e!s}", exc_info=True
)
logger.exception("Error listing sessions for user %s: %s", current_user.id, e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to retrieve sessions",
@@ -161,8 +157,10 @@ async def revoke_session(
# Verify session belongs to current user
if str(session.user_id) != str(current_user.id):
logger.warning(
f"User {current_user.id} attempted to revoke session {session_id} "
f"belonging to user {session.user_id}"
"User %s attempted to revoke session %s belonging to user %s",
current_user.id,
session_id,
session.user_id,
)
raise AuthorizationError(
message="You can only revoke your own sessions",
@@ -173,8 +171,10 @@ async def revoke_session(
await session_service.deactivate(db, session_id=str(session_id))
logger.info(
f"User {current_user.id} revoked session {session_id} "
f"({session.device_name})"
"User %s revoked session %s (%s)",
current_user.id,
session_id,
session.device_name,
)
return MessageResponse(
@@ -185,7 +185,7 @@ async def revoke_session(
except (NotFoundError, AuthorizationError):
raise
except Exception as e:
logger.error(f"Error revoking session {session_id}: {e!s}", exc_info=True)
logger.exception("Error revoking session %s: %s", session_id, e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to revoke session",
@@ -229,7 +229,7 @@ async def cleanup_expired_sessions(
)
logger.info(
f"User {current_user.id} cleaned up {deleted_count} expired sessions"
"User %s cleaned up %s expired sessions", current_user.id, deleted_count
)
return MessageResponse(
@@ -237,9 +237,8 @@ async def cleanup_expired_sessions(
)
except Exception as e:
logger.error(
f"Error cleaning up sessions for user {current_user.id}: {e!s}",
exc_info=True,
logger.exception(
"Error cleaning up sessions for user %s: %s", current_user.id, e
)
await db.rollback()
raise HTTPException(

View File

@@ -90,7 +90,7 @@ async def list_users(
return PaginatedResponse(data=users, pagination=pagination_meta)
except Exception as e:
logger.error(f"Error listing users: {e!s}", exc_info=True)
logger.exception("Error listing users: %s", e)
raise
@@ -143,15 +143,13 @@ async def update_current_user(
updated_user = await user_service.update_user(
db, user=current_user, obj_in=user_update
)
logger.info(f"User {current_user.id} updated their profile")
logger.info("User %s updated their profile", current_user.id)
return updated_user
except ValueError as e:
logger.error(f"Error updating user {current_user.id}: {e!s}")
logger.error("Error updating user %s: %s", current_user.id, e)
raise
except Exception as e:
logger.error(
f"Unexpected error updating user {current_user.id}: {e!s}", exc_info=True
)
logger.exception("Unexpected error updating user %s: %s", current_user.id, e)
raise
@@ -184,7 +182,9 @@ async def get_user_by_id(
# Check permissions
if str(user_id) != str(current_user.id) and not current_user.is_superuser:
logger.warning(
f"User {current_user.id} attempted to access user {user_id} without permission"
"User %s attempted to access user %s without permission",
current_user.id,
user_id,
)
raise AuthorizationError(
message="Not enough permissions to view this user",
@@ -229,7 +229,9 @@ async def update_user(
if not is_own_profile and not current_user.is_superuser:
logger.warning(
f"User {current_user.id} attempted to update user {user_id} without permission"
"User %s attempted to update user %s without permission",
current_user.id,
user_id,
)
raise AuthorizationError(
message="Not enough permissions to update this user",
@@ -241,13 +243,13 @@ async def update_user(
try:
updated_user = await user_service.update_user(db, user=user, obj_in=user_update)
logger.info(f"User {user_id} updated by {current_user.id}")
logger.info("User %s updated by %s", user_id, current_user.id)
return updated_user
except ValueError as e:
logger.error(f"Error updating user {user_id}: {e!s}")
logger.error("Error updating user %s: %s", user_id, e)
raise
except Exception as e:
logger.error(f"Unexpected error updating user {user_id}: {e!s}", exc_info=True)
logger.exception("Unexpected error updating user %s: %s", user_id, e)
raise
@@ -287,19 +289,19 @@ async def change_current_user_password(
)
if success:
logger.info(f"User {current_user.id} changed their password")
logger.info("User %s changed their password", current_user.id)
return MessageResponse(
success=True, message="Password changed successfully"
)
except AuthenticationError as e:
logger.warning(
f"Failed password change attempt for user {current_user.id}: {e!s}"
"Failed password change attempt for user %s: %s", current_user.id, e
)
raise AuthorizationError(
message=str(e), error_code=ErrorCode.INVALID_CREDENTIALS
)
except Exception as e:
logger.error(f"Error changing password for user {current_user.id}: {e!s}")
logger.error("Error changing password for user %s: %s", current_user.id, e)
raise
@@ -343,13 +345,13 @@ async def delete_user(
try:
# Use soft delete instead of hard delete
await user_service.soft_delete_user(db, str(user_id))
logger.info(f"User {user_id} soft-deleted by {current_user.id}")
logger.info("User %s soft-deleted by %s", user_id, current_user.id)
return MessageResponse(
success=True, message=f"User {user_id} deleted successfully"
)
except ValueError as e:
logger.error(f"Error deleting user {user_id}: {e!s}")
logger.error("Error deleting user %s: %s", user_id, e)
raise
except Exception as e:
logger.error(f"Unexpected error deleting user {user_id}: {e!s}", exc_info=True)
logger.exception("Unexpected error deleting user %s: %s", user_id, e)
raise