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

@@ -68,7 +68,7 @@ class BaseRepository[
else:
uuid_obj = uuid.UUID(str(id))
except (ValueError, AttributeError, TypeError) as e:
logger.warning(f"Invalid UUID format: {id} - {e!s}")
logger.warning("Invalid UUID format: %s - %s", id, e)
return None
try:
@@ -81,7 +81,9 @@ class BaseRepository[
result = await db.execute(query)
return result.scalar_one_or_none()
except Exception as e:
logger.error(f"Error retrieving {self.model.__name__} with id {id}: {e!s}")
logger.error(
"Error retrieving %s with id %s: %s", self.model.__name__, id, e
)
raise
async def get_multi(
@@ -113,7 +115,7 @@ class BaseRepository[
return list(result.scalars().all())
except Exception as e:
logger.error(
f"Error retrieving multiple {self.model.__name__} records: {e!s}"
"Error retrieving multiple %s records: %s", self.model.__name__, e
)
raise
@@ -138,22 +140,24 @@ class BaseRepository[
error_msg = str(e.orig) if hasattr(e, "orig") else str(e)
if "unique" in error_msg.lower() or "duplicate" in error_msg.lower():
logger.warning(
f"Duplicate entry attempted for {self.model.__name__}: {error_msg}"
"Duplicate entry attempted for %s: %s",
self.model.__name__,
error_msg,
)
raise DuplicateEntryError(
f"A {self.model.__name__} with this data already exists"
)
logger.error(f"Integrity error creating {self.model.__name__}: {error_msg}")
logger.error(
"Integrity error creating %s: %s", self.model.__name__, error_msg
)
raise IntegrityConstraintError(f"Database integrity error: {error_msg}")
except (OperationalError, DataError) as e: # pragma: no cover
await db.rollback()
logger.error(f"Database error creating {self.model.__name__}: {e!s}")
logger.error("Database error creating %s: %s", self.model.__name__, e)
raise IntegrityConstraintError(f"Database operation failed: {e!s}")
except Exception as e: # pragma: no cover
await db.rollback()
logger.error(
f"Unexpected error creating {self.model.__name__}: {e!s}", exc_info=True
)
logger.exception("Unexpected error creating %s: %s", self.model.__name__, e)
raise
async def update(
@@ -184,22 +188,24 @@ class BaseRepository[
error_msg = str(e.orig) if hasattr(e, "orig") else str(e)
if "unique" in error_msg.lower() or "duplicate" in error_msg.lower():
logger.warning(
f"Duplicate entry attempted for {self.model.__name__}: {error_msg}"
"Duplicate entry attempted for %s: %s",
self.model.__name__,
error_msg,
)
raise DuplicateEntryError(
f"A {self.model.__name__} with this data already exists"
)
logger.error(f"Integrity error updating {self.model.__name__}: {error_msg}")
logger.error(
"Integrity error updating %s: %s", self.model.__name__, error_msg
)
raise IntegrityConstraintError(f"Database integrity error: {error_msg}")
except (OperationalError, DataError) as e:
await db.rollback()
logger.error(f"Database error updating {self.model.__name__}: {e!s}")
logger.error("Database error updating %s: %s", self.model.__name__, e)
raise IntegrityConstraintError(f"Database operation failed: {e!s}")
except Exception as e:
await db.rollback()
logger.error(
f"Unexpected error updating {self.model.__name__}: {e!s}", exc_info=True
)
logger.exception("Unexpected error updating %s: %s", self.model.__name__, e)
raise
async def remove(self, db: AsyncSession, *, id: str) -> ModelType | None:
@@ -210,7 +216,7 @@ class BaseRepository[
else:
uuid_obj = uuid.UUID(str(id))
except (ValueError, AttributeError, TypeError) as e:
logger.warning(f"Invalid UUID format for deletion: {id} - {e!s}")
logger.warning("Invalid UUID format for deletion: %s - %s", id, e)
return None
try:
@@ -221,7 +227,7 @@ class BaseRepository[
if obj is None:
logger.warning(
f"{self.model.__name__} with id {id} not found for deletion"
"%s with id %s not found for deletion", self.model.__name__, id
)
return None
@@ -231,15 +237,16 @@ class BaseRepository[
except IntegrityError as e:
await db.rollback()
error_msg = str(e.orig) if hasattr(e, "orig") else str(e)
logger.error(f"Integrity error deleting {self.model.__name__}: {error_msg}")
logger.error(
"Integrity error deleting %s: %s", self.model.__name__, error_msg
)
raise IntegrityConstraintError(
f"Cannot delete {self.model.__name__}: referenced by other records"
)
except Exception as e:
await db.rollback()
logger.error(
f"Error deleting {self.model.__name__} with id {id}: {e!s}",
exc_info=True,
logger.exception(
"Error deleting %s with id %s: %s", self.model.__name__, id, e
)
raise
@@ -298,7 +305,7 @@ class BaseRepository[
return items, total
except Exception as e: # pragma: no cover
logger.error(
f"Error retrieving paginated {self.model.__name__} records: {e!s}"
"Error retrieving paginated %s records: %s", self.model.__name__, e
)
raise
@@ -308,7 +315,7 @@ class BaseRepository[
result = await db.execute(select(func.count(self.model.id)))
return result.scalar_one()
except Exception as e:
logger.error(f"Error counting {self.model.__name__} records: {e!s}")
logger.error("Error counting %s records: %s", self.model.__name__, e)
raise
async def exists(self, db: AsyncSession, id: str) -> bool:
@@ -330,7 +337,7 @@ class BaseRepository[
else:
uuid_obj = uuid.UUID(str(id))
except (ValueError, AttributeError, TypeError) as e:
logger.warning(f"Invalid UUID format for soft deletion: {id} - {e!s}")
logger.warning("Invalid UUID format for soft deletion: %s - %s", id, e)
return None
try:
@@ -341,12 +348,12 @@ class BaseRepository[
if obj is None:
logger.warning(
f"{self.model.__name__} with id {id} not found for soft deletion"
"%s with id %s not found for soft deletion", self.model.__name__, id
)
return None
if not hasattr(self.model, "deleted_at"):
logger.error(f"{self.model.__name__} does not support soft deletes")
logger.error("%s does not support soft deletes", self.model.__name__)
raise InvalidInputError(
f"{self.model.__name__} does not have a deleted_at column"
)
@@ -358,9 +365,8 @@ class BaseRepository[
return obj
except Exception as e:
await db.rollback()
logger.error(
f"Error soft deleting {self.model.__name__} with id {id}: {e!s}",
exc_info=True,
logger.exception(
"Error soft deleting %s with id %s: %s", self.model.__name__, id, e
)
raise
@@ -376,7 +382,7 @@ class BaseRepository[
else:
uuid_obj = uuid.UUID(str(id))
except (ValueError, AttributeError, TypeError) as e:
logger.warning(f"Invalid UUID format for restoration: {id} - {e!s}")
logger.warning("Invalid UUID format for restoration: %s - %s", id, e)
return None
try:
@@ -388,14 +394,16 @@ class BaseRepository[
)
obj = result.scalar_one_or_none()
else:
logger.error(f"{self.model.__name__} does not support soft deletes")
logger.error("%s does not support soft deletes", self.model.__name__)
raise InvalidInputError(
f"{self.model.__name__} does not have a deleted_at column"
)
if obj is None:
logger.warning(
f"Soft-deleted {self.model.__name__} with id {id} not found for restoration"
"Soft-deleted %s with id %s not found for restoration",
self.model.__name__,
id,
)
return None
@@ -406,8 +414,7 @@ class BaseRepository[
return obj
except Exception as e:
await db.rollback()
logger.error(
f"Error restoring {self.model.__name__} with id {id}: {e!s}",
exc_info=True,
logger.exception(
"Error restoring %s with id %s: %s", self.model.__name__, id, e
)
raise

View File

@@ -50,7 +50,10 @@ class OAuthAccountRepository(
return result.scalar_one_or_none()
except Exception as e: # pragma: no cover
logger.error(
f"Error getting OAuth account for {provider}:{provider_user_id}: {e!s}"
"Error getting OAuth account for %s:%s: %s",
provider,
provider_user_id,
e,
)
raise
@@ -76,7 +79,7 @@ class OAuthAccountRepository(
return result.scalar_one_or_none()
except Exception as e: # pragma: no cover
logger.error(
f"Error getting OAuth account for {provider} email {email}: {e!s}"
"Error getting OAuth account for %s email %s: %s", provider, email, e
)
raise
@@ -97,7 +100,7 @@ class OAuthAccountRepository(
)
return list(result.scalars().all())
except Exception as e: # pragma: no cover
logger.error(f"Error getting OAuth accounts for user {user_id}: {e!s}")
logger.error("Error getting OAuth accounts for user %s: %s", user_id, e)
raise
async def get_user_account_by_provider(
@@ -122,7 +125,10 @@ class OAuthAccountRepository(
return result.scalar_one_or_none()
except Exception as e: # pragma: no cover
logger.error(
f"Error getting OAuth account for user {user_id}, provider {provider}: {e!s}"
"Error getting OAuth account for user %s, provider %s: %s",
user_id,
provider,
e,
)
raise
@@ -145,7 +151,9 @@ class OAuthAccountRepository(
await db.refresh(db_obj)
logger.info(
f"OAuth account created: {obj_in.provider} linked to user {obj_in.user_id}"
"OAuth account created: %s linked to user %s",
obj_in.provider,
obj_in.user_id,
)
return db_obj
except IntegrityError as e: # pragma: no cover
@@ -153,16 +161,18 @@ class OAuthAccountRepository(
error_msg = str(e.orig) if hasattr(e, "orig") else str(e)
if "uq_oauth_provider_user" in error_msg.lower():
logger.warning(
f"OAuth account already exists: {obj_in.provider}:{obj_in.provider_user_id}"
"OAuth account already exists: %s:%s",
obj_in.provider,
obj_in.provider_user_id,
)
raise DuplicateEntryError(
f"This {obj_in.provider} account is already linked to another user"
)
logger.error(f"Integrity error creating OAuth account: {error_msg}")
logger.error("Integrity error creating OAuth account: %s", error_msg)
raise DuplicateEntryError(f"Failed to create OAuth account: {error_msg}")
except Exception as e: # pragma: no cover
await db.rollback()
logger.error(f"Error creating OAuth account: {e!s}", exc_info=True)
logger.exception("Error creating OAuth account: %s", e)
raise
async def delete_account(
@@ -189,18 +199,20 @@ class OAuthAccountRepository(
deleted = result.rowcount > 0
if deleted:
logger.info(
f"OAuth account deleted: {provider} unlinked from user {user_id}"
"OAuth account deleted: %s unlinked from user %s", provider, user_id
)
else:
logger.warning(
f"OAuth account not found for deletion: {provider} for user {user_id}"
"OAuth account not found for deletion: %s for user %s",
provider,
user_id,
)
return deleted
except Exception as e: # pragma: no cover
await db.rollback()
logger.error(
f"Error deleting OAuth account {provider} for user {user_id}: {e!s}"
"Error deleting OAuth account %s for user %s: %s", provider, user_id, e
)
raise
@@ -229,7 +241,7 @@ class OAuthAccountRepository(
return account
except Exception as e: # pragma: no cover
await db.rollback()
logger.error(f"Error updating OAuth tokens: {e!s}")
logger.error("Error updating OAuth tokens: %s", e)
raise

View File

@@ -42,7 +42,7 @@ class OAuthClientRepository(
)
return result.scalar_one_or_none()
except Exception as e: # pragma: no cover
logger.error(f"Error getting OAuth client {client_id}: {e!s}")
logger.error("Error getting OAuth client %s: %s", client_id, e)
raise
async def create_client(
@@ -80,17 +80,17 @@ class OAuthClientRepository(
await db.refresh(db_obj)
logger.info(
f"OAuth client created: {obj_in.client_name} ({client_id[:8]}...)"
"OAuth client created: %s (%s...)", obj_in.client_name, client_id[:8]
)
return db_obj, client_secret
except IntegrityError as e: # pragma: no cover
await db.rollback()
error_msg = str(e.orig) if hasattr(e, "orig") else str(e)
logger.error(f"Error creating OAuth client: {error_msg}")
logger.error("Error creating OAuth client: %s", error_msg)
raise DuplicateEntryError(f"Failed to create OAuth client: {error_msg}")
except Exception as e: # pragma: no cover
await db.rollback()
logger.error(f"Error creating OAuth client: {e!s}", exc_info=True)
logger.exception("Error creating OAuth client: %s", e)
raise
async def deactivate_client(
@@ -107,11 +107,11 @@ class OAuthClientRepository(
await db.commit()
await db.refresh(client)
logger.info(f"OAuth client deactivated: {client.client_name}")
logger.info("OAuth client deactivated: %s", client.client_name)
return client
except Exception as e: # pragma: no cover
await db.rollback()
logger.error(f"Error deactivating OAuth client {client_id}: {e!s}")
logger.error("Error deactivating OAuth client %s: %s", client_id, e)
raise
async def validate_redirect_uri(
@@ -125,7 +125,7 @@ class OAuthClientRepository(
return redirect_uri in (client.redirect_uris or [])
except Exception as e: # pragma: no cover
logger.error(f"Error validating redirect URI: {e!s}")
logger.error("Error validating redirect URI: %s", e)
return False
async def verify_client_secret(
@@ -158,7 +158,7 @@ class OAuthClientRepository(
secret_hash = hashlib.sha256(client_secret.encode()).hexdigest()
return secrets.compare_digest(stored_hash, secret_hash)
except Exception as e: # pragma: no cover
logger.error(f"Error verifying client secret: {e!s}")
logger.error("Error verifying client secret: %s", e)
return False
async def get_all_clients(
@@ -173,7 +173,7 @@ class OAuthClientRepository(
result = await db.execute(query)
return list(result.scalars().all())
except Exception as e: # pragma: no cover
logger.error(f"Error getting all OAuth clients: {e!s}")
logger.error("Error getting all OAuth clients: %s", e)
raise
async def delete_client(self, db: AsyncSession, *, client_id: str) -> bool:
@@ -186,14 +186,14 @@ class OAuthClientRepository(
deleted = result.rowcount > 0
if deleted:
logger.info(f"OAuth client deleted: {client_id}")
logger.info("OAuth client deleted: %s", client_id)
else:
logger.warning(f"OAuth client not found for deletion: {client_id}")
logger.warning("OAuth client not found for deletion: %s", client_id)
return deleted
except Exception as e: # pragma: no cover
await db.rollback()
logger.error(f"Error deleting OAuth client {client_id}: {e!s}")
logger.error("Error deleting OAuth client %s: %s", client_id, e)
raise

View File

@@ -42,16 +42,16 @@ class OAuthStateRepository(BaseRepository[OAuthState, OAuthStateCreate, EmptySch
await db.commit()
await db.refresh(db_obj)
logger.debug(f"OAuth state created for {obj_in.provider}")
logger.debug("OAuth state created for %s", obj_in.provider)
return db_obj
except IntegrityError as e: # pragma: no cover
await db.rollback()
error_msg = str(e.orig) if hasattr(e, "orig") else str(e)
logger.error(f"OAuth state collision: {error_msg}")
logger.error("OAuth state collision: %s", error_msg)
raise DuplicateEntryError("Failed to create OAuth state, please retry")
except Exception as e: # pragma: no cover
await db.rollback()
logger.error(f"Error creating OAuth state: {e!s}", exc_info=True)
logger.exception("Error creating OAuth state: %s", e)
raise
async def get_and_consume_state(
@@ -65,7 +65,7 @@ class OAuthStateRepository(BaseRepository[OAuthState, OAuthStateCreate, EmptySch
db_obj = result.scalar_one_or_none()
if db_obj is None:
logger.warning(f"OAuth state not found: {state[:8]}...")
logger.warning("OAuth state not found: %s...", state[:8])
return None
now = datetime.now(UTC)
@@ -74,7 +74,7 @@ class OAuthStateRepository(BaseRepository[OAuthState, OAuthStateCreate, EmptySch
expires_at = expires_at.replace(tzinfo=UTC)
if expires_at < now:
logger.warning(f"OAuth state expired: {state[:8]}...")
logger.warning("OAuth state expired: %s...", state[:8])
await db.delete(db_obj)
await db.commit()
return None
@@ -82,11 +82,11 @@ class OAuthStateRepository(BaseRepository[OAuthState, OAuthStateCreate, EmptySch
await db.delete(db_obj)
await db.commit()
logger.debug(f"OAuth state consumed: {state[:8]}...")
logger.debug("OAuth state consumed: %s...", state[:8])
return db_obj
except Exception as e: # pragma: no cover
await db.rollback()
logger.error(f"Error consuming OAuth state: {e!s}")
logger.error("Error consuming OAuth state: %s", e)
raise
async def cleanup_expired(self, db: AsyncSession) -> int:
@@ -100,12 +100,12 @@ class OAuthStateRepository(BaseRepository[OAuthState, OAuthStateCreate, EmptySch
count = result.rowcount
if count > 0:
logger.info(f"Cleaned up {count} expired OAuth states")
logger.info("Cleaned up %s expired OAuth states", count)
return count
except Exception as e: # pragma: no cover
await db.rollback()
logger.error(f"Error cleaning up expired OAuth states: {e!s}")
logger.error("Error cleaning up expired OAuth states: %s", e)
raise

View File

@@ -35,7 +35,7 @@ class OrganizationRepository(
)
return result.scalar_one_or_none()
except Exception as e:
logger.error(f"Error getting organization by slug {slug}: {e!s}")
logger.error("Error getting organization by slug %s: %s", slug, e)
raise
async def create(
@@ -62,17 +62,15 @@ class OrganizationRepository(
or "unique" in error_msg.lower()
or "duplicate" in error_msg.lower()
):
logger.warning(f"Duplicate slug attempted: {obj_in.slug}")
logger.warning("Duplicate slug attempted: %s", obj_in.slug)
raise DuplicateEntryError(
f"Organization with slug '{obj_in.slug}' already exists"
)
logger.error(f"Integrity error creating organization: {error_msg}")
logger.error("Integrity error creating organization: %s", error_msg)
raise IntegrityConstraintError(f"Database integrity error: {error_msg}")
except Exception as e:
await db.rollback()
logger.error(
f"Unexpected error creating organization: {e!s}", exc_info=True
)
logger.exception("Unexpected error creating organization: %s", e)
raise
async def get_multi_with_filters(
@@ -117,7 +115,7 @@ class OrganizationRepository(
return organizations, total
except Exception as e:
logger.error(f"Error getting organizations with filters: {e!s}")
logger.error("Error getting organizations with filters: %s", e)
raise
async def get_member_count(self, db: AsyncSession, *, organization_id: UUID) -> int:
@@ -134,7 +132,7 @@ class OrganizationRepository(
return result.scalar_one() or 0
except Exception as e:
logger.error(
f"Error getting member count for organization {organization_id}: {e!s}"
"Error getting member count for organization %s: %s", organization_id, e
)
raise
@@ -207,9 +205,7 @@ class OrganizationRepository(
return orgs_with_counts, total
except Exception as e:
logger.error(
f"Error getting organizations with member counts: {e!s}", exc_info=True
)
logger.exception("Error getting organizations with member counts: %s", e)
raise
async def add_user(
@@ -259,11 +255,11 @@ class OrganizationRepository(
return user_org
except IntegrityError as e:
await db.rollback()
logger.error(f"Integrity error adding user to organization: {e!s}")
logger.error("Integrity error adding user to organization: %s", e)
raise IntegrityConstraintError("Failed to add user to organization")
except Exception as e:
await db.rollback()
logger.error(f"Error adding user to organization: {e!s}", exc_info=True)
logger.exception("Error adding user to organization: %s", e)
raise
async def remove_user(
@@ -289,7 +285,7 @@ class OrganizationRepository(
return True
except Exception as e:
await db.rollback()
logger.error(f"Error removing user from organization: {e!s}", exc_info=True)
logger.exception("Error removing user from organization: %s", e)
raise
async def update_user_role(
@@ -324,7 +320,7 @@ class OrganizationRepository(
return user_org
except Exception as e:
await db.rollback()
logger.error(f"Error updating user role: {e!s}", exc_info=True)
logger.exception("Error updating user role: %s", e)
raise
async def get_organization_members(
@@ -384,7 +380,7 @@ class OrganizationRepository(
return members, total
except Exception as e:
logger.error(f"Error getting organization members: {e!s}")
logger.error("Error getting organization members: %s", e)
raise
async def get_user_organizations(
@@ -407,7 +403,7 @@ class OrganizationRepository(
result = await db.execute(query)
return list(result.scalars().all())
except Exception as e:
logger.error(f"Error getting user organizations: {e!s}")
logger.error("Error getting user organizations: %s", e)
raise
async def get_user_organizations_with_details(
@@ -456,9 +452,7 @@ class OrganizationRepository(
]
except Exception as e:
logger.error(
f"Error getting user organizations with details: {e!s}", exc_info=True
)
logger.exception("Error getting user organizations with details: %s", e)
raise
async def get_user_role_in_org(
@@ -479,7 +473,7 @@ class OrganizationRepository(
return user_org.role if user_org else None # pyright: ignore[reportReturnType]
except Exception as e:
logger.error(f"Error getting user role in org: {e!s}")
logger.error("Error getting user role in org: %s", e)
raise
async def is_user_org_owner(

View File

@@ -29,7 +29,7 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
)
return result.scalar_one_or_none()
except Exception as e:
logger.error(f"Error getting session by JTI {jti}: {e!s}")
logger.error("Error getting session by JTI %s: %s", jti, e)
raise
async def get_active_by_jti(
@@ -47,7 +47,7 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
)
return result.scalar_one_or_none()
except Exception as e:
logger.error(f"Error getting active session by JTI {jti}: {e!s}")
logger.error("Error getting active session by JTI %s: %s", jti, e)
raise
async def get_user_sessions(
@@ -74,7 +74,7 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
result = await db.execute(query)
return list(result.scalars().all())
except Exception as e:
logger.error(f"Error getting sessions for user {user_id}: {e!s}")
logger.error("Error getting sessions for user %s: %s", user_id, e)
raise
async def create_session(
@@ -100,14 +100,16 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
await db.refresh(db_obj)
logger.info(
f"Session created for user {obj_in.user_id} from {obj_in.device_name} "
f"(IP: {obj_in.ip_address})"
"Session created for user %s from %s (IP: %s)",
obj_in.user_id,
obj_in.device_name,
obj_in.ip_address,
)
return db_obj
except Exception as e:
await db.rollback()
logger.error(f"Error creating session: {e!s}", exc_info=True)
logger.exception("Error creating session: %s", e)
raise IntegrityConstraintError(f"Failed to create session: {e!s}")
async def deactivate(
@@ -117,7 +119,7 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
try:
session = await self.get(db, id=session_id)
if not session:
logger.warning(f"Session {session_id} not found for deactivation")
logger.warning("Session %s not found for deactivation", session_id)
return None
session.is_active = False
@@ -126,14 +128,16 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
await db.refresh(session)
logger.info(
f"Session {session_id} deactivated for user {session.user_id} "
f"({session.device_name})"
"Session %s deactivated for user %s (%s)",
session_id,
session.user_id,
session.device_name,
)
return session
except Exception as e:
await db.rollback()
logger.error(f"Error deactivating session {session_id}: {e!s}")
logger.error("Error deactivating session %s: %s", session_id, e)
raise
async def deactivate_all_user_sessions(
@@ -154,12 +158,12 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
count = result.rowcount
logger.info(f"Deactivated {count} sessions for user {user_id}")
logger.info("Deactivated %s sessions for user %s", count, user_id)
return count
except Exception as e:
await db.rollback()
logger.error(f"Error deactivating all sessions for user {user_id}: {e!s}")
logger.error("Error deactivating all sessions for user %s: %s", user_id, e)
raise
async def update_last_used(
@@ -174,7 +178,7 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
return session
except Exception as e:
await db.rollback()
logger.error(f"Error updating last_used for session {session.id}: {e!s}")
logger.error("Error updating last_used for session %s: %s", session.id, e)
raise
async def update_refresh_token(
@@ -197,7 +201,7 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
except Exception as e:
await db.rollback()
logger.error(
f"Error updating refresh token for session {session.id}: {e!s}"
"Error updating refresh token for session %s: %s", session.id, e
)
raise
@@ -221,12 +225,12 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
count = result.rowcount
if count > 0:
logger.info(f"Cleaned up {count} expired sessions using bulk DELETE")
logger.info("Cleaned up %s expired sessions using bulk DELETE", count)
return count
except Exception as e:
await db.rollback()
logger.error(f"Error cleaning up expired sessions: {e!s}")
logger.error("Error cleaning up expired sessions: %s", e)
raise
async def cleanup_expired_for_user(self, db: AsyncSession, *, user_id: str) -> int:
@@ -235,7 +239,7 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
try:
uuid_obj = uuid.UUID(user_id)
except (ValueError, AttributeError):
logger.error(f"Invalid UUID format: {user_id}")
logger.error("Invalid UUID format: %s", user_id)
raise InvalidInputError(f"Invalid user ID format: {user_id}")
now = datetime.now(UTC)
@@ -255,14 +259,16 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
if count > 0:
logger.info(
f"Cleaned up {count} expired sessions for user {user_id} using bulk DELETE"
"Cleaned up %s expired sessions for user %s using bulk DELETE",
count,
user_id,
)
return count
except Exception as e:
await db.rollback()
logger.error(
f"Error cleaning up expired sessions for user {user_id}: {e!s}"
"Error cleaning up expired sessions for user %s: %s", user_id, e
)
raise
@@ -278,7 +284,7 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
)
return result.scalar_one()
except Exception as e:
logger.error(f"Error counting sessions for user {user_id}: {e!s}")
logger.error("Error counting sessions for user %s: %s", user_id, e)
raise
async def get_all_sessions(
@@ -319,7 +325,7 @@ class SessionRepository(BaseRepository[UserSession, SessionCreate, SessionUpdate
return sessions, total
except Exception as e:
logger.error(f"Error getting all sessions: {e!s}", exc_info=True)
logger.exception("Error getting all sessions: %s", e)
raise

View File

@@ -28,7 +28,7 @@ class UserRepository(BaseRepository[User, UserCreate, UserUpdate]):
result = await db.execute(select(User).where(User.email == email))
return result.scalar_one_or_none()
except Exception as e:
logger.error(f"Error getting user by email {email}: {e!s}")
logger.error("Error getting user by email %s: %s", email, e)
raise
async def create(self, db: AsyncSession, *, obj_in: UserCreate) -> User:
@@ -57,15 +57,15 @@ class UserRepository(BaseRepository[User, UserCreate, UserUpdate]):
await db.rollback()
error_msg = str(e.orig) if hasattr(e, "orig") else str(e)
if "email" in error_msg.lower():
logger.warning(f"Duplicate email attempted: {obj_in.email}")
logger.warning("Duplicate email attempted: %s", obj_in.email)
raise DuplicateEntryError(
f"User with email {obj_in.email} already exists"
)
logger.error(f"Integrity error creating user: {error_msg}")
logger.error("Integrity error creating user: %s", error_msg)
raise DuplicateEntryError(f"Database integrity error: {error_msg}")
except Exception as e:
await db.rollback()
logger.error(f"Unexpected error creating user: {e!s}", exc_info=True)
logger.exception("Unexpected error creating user: %s", e)
raise
async def create_oauth_user(
@@ -93,13 +93,13 @@ class UserRepository(BaseRepository[User, UserCreate, UserUpdate]):
await db.rollback()
error_msg = str(e.orig) if hasattr(e, "orig") else str(e)
if "email" in error_msg.lower():
logger.warning(f"Duplicate email attempted: {email}")
logger.warning("Duplicate email attempted: %s", email)
raise DuplicateEntryError(f"User with email {email} already exists")
logger.error(f"Integrity error creating OAuth user: {error_msg}")
logger.error("Integrity error creating OAuth user: %s", error_msg)
raise DuplicateEntryError(f"Database integrity error: {error_msg}")
except Exception as e:
await db.rollback()
logger.error(f"Unexpected error creating OAuth user: {e!s}", exc_info=True)
logger.exception("Unexpected error creating OAuth user: %s", e)
raise
async def update(
@@ -184,7 +184,7 @@ class UserRepository(BaseRepository[User, UserCreate, UserUpdate]):
return users, total
except Exception as e:
logger.error(f"Error retrieving paginated users: {e!s}")
logger.error("Error retrieving paginated users: %s", e)
raise
async def bulk_update_status(
@@ -206,12 +206,14 @@ class UserRepository(BaseRepository[User, UserCreate, UserUpdate]):
await db.commit()
updated_count = result.rowcount
logger.info(f"Bulk updated {updated_count} users to is_active={is_active}")
logger.info(
"Bulk updated %s users to is_active=%s", updated_count, is_active
)
return updated_count
except Exception as e:
await db.rollback()
logger.error(f"Error bulk updating user status: {e!s}", exc_info=True)
logger.exception("Error bulk updating user status: %s", e)
raise
async def bulk_soft_delete(
@@ -246,12 +248,12 @@ class UserRepository(BaseRepository[User, UserCreate, UserUpdate]):
await db.commit()
deleted_count = result.rowcount
logger.info(f"Bulk soft deleted {deleted_count} users")
logger.info("Bulk soft deleted %s users", deleted_count)
return deleted_count
except Exception as e:
await db.rollback()
logger.error(f"Error bulk deleting users: {e!s}", exc_info=True)
logger.exception("Error bulk deleting users: %s", e)
raise
def is_active(self, user: User) -> bool: