fix: narrow exception handling and support migrate_to for broken credentials
- Catch only ValueError (decryption errors) instead of broad Exception so NotFoundError and other failures propagate correctly - Support migrate_to parameter in the fallback delete path so linked models can be reassigned instead of always cascade-deleted - Sanitize decryption_error message to not expose raw exception details
This commit is contained in:
parent
ba01f7df4e
commit
0c2522074d
2 changed files with 24 additions and 8 deletions
|
|
@ -269,7 +269,7 @@ async def delete_credential(
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
cred = await Credential.get(credential_id)
|
cred = await Credential.get(credential_id)
|
||||||
except Exception as decrypt_err:
|
except ValueError as decrypt_err:
|
||||||
# Credential exists but can't be decrypted (wrong encryption key).
|
# Credential exists but can't be decrypted (wrong encryption key).
|
||||||
# Fall back to direct DB operations for deletion.
|
# Fall back to direct DB operations for deletion.
|
||||||
logger.warning(
|
logger.warning(
|
||||||
|
|
@ -277,17 +277,33 @@ async def delete_credential(
|
||||||
f"falling back to direct delete: {decrypt_err}"
|
f"falling back to direct delete: {decrypt_err}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Delete linked models directly
|
# Query linked models
|
||||||
linked = await repo_query(
|
linked = await repo_query(
|
||||||
"SELECT * FROM model WHERE credential = $cred_id",
|
"SELECT * FROM model WHERE credential = $cred_id",
|
||||||
{"cred_id": ensure_record_id(credential_id)},
|
{"cred_id": ensure_record_id(credential_id)},
|
||||||
)
|
)
|
||||||
deleted_models = 0
|
deleted_models = 0
|
||||||
for model_row in linked:
|
|
||||||
model_id = str(model_row.get("id", ""))
|
if linked and migrate_to:
|
||||||
if model_id:
|
# Migrate models to another credential
|
||||||
await repo_delete(model_id)
|
target_cred = await Credential.get(migrate_to)
|
||||||
deleted_models += 1
|
for model_row in linked:
|
||||||
|
model_id = str(model_row.get("id", ""))
|
||||||
|
if model_id:
|
||||||
|
await repo_query(
|
||||||
|
"UPDATE $model_id SET credential = $target_id",
|
||||||
|
{
|
||||||
|
"model_id": ensure_record_id(model_id),
|
||||||
|
"target_id": ensure_record_id(target_cred.id),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
elif linked:
|
||||||
|
# Cascade-delete linked models
|
||||||
|
for model_row in linked:
|
||||||
|
model_id = str(model_row.get("id", ""))
|
||||||
|
if model_id:
|
||||||
|
await repo_delete(model_id)
|
||||||
|
deleted_models += 1
|
||||||
|
|
||||||
# Delete the credential itself
|
# Delete the credential itself
|
||||||
await repo_delete(credential_id)
|
await repo_delete(credential_id)
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ class Credential(ObjectModel):
|
||||||
name=row.get("name", "Unknown"),
|
name=row.get("name", "Unknown"),
|
||||||
provider=row.get("provider", "unknown"),
|
provider=row.get("provider", "unknown"),
|
||||||
modalities=row.get("modalities", []),
|
modalities=row.get("modalities", []),
|
||||||
decryption_error=f"Failed to decrypt API key. The encryption key may have changed. Error: {e}",
|
decryption_error="Failed to decrypt API key. The encryption key may have changed.",
|
||||||
)
|
)
|
||||||
# Preserve the DB id, created, updated from the raw row
|
# Preserve the DB id, created, updated from the raw row
|
||||||
if row.get("id"):
|
if row.get("id"):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue