Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add connector deletion failure message #2392

Merged
merged 5 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""add ccpair deletion failure message

Revision ID: 0ebb1d516877
Revises: 52a219fb5233
Create Date: 2024-09-10 15:03:48.233926

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "0ebb1d516877"
down_revision = "52a219fb5233"
branch_labels = None
depends_on = None


def upgrade() -> None:
op.add_column(
"connector_credential_pair",
sa.Column("deletion_failure_message", sa.String(), nullable=True),
)


def downgrade() -> None:
op.drop_column("connector_credential_pair", "deletion_failure_message")
24 changes: 16 additions & 8 deletions backend/danswer/background/celery/celery_app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import traceback
from datetime import timedelta
from typing import Any
from typing import cast
Expand Down Expand Up @@ -40,6 +41,7 @@
from danswer.configs.constants import PostgresAdvisoryLocks
from danswer.connectors.factory import instantiate_connector
from danswer.connectors.models import InputType
from danswer.db.connector_credential_pair import add_deletion_failure_message
from danswer.db.connector_credential_pair import (
get_connector_credential_pair,
)
Expand Down Expand Up @@ -97,6 +99,7 @@ def cleanup_connector_credential_pair_task(
Needs to potentially update a large number of Postgres and Vespa docs, including deleting them
or updating the ACL"""
engine = get_sqlalchemy_engine()

with Session(engine) as db_session:
# validate that the connector / credential pair is deletable
cc_pair = get_connector_credential_pair(
Expand All @@ -109,14 +112,13 @@ def cleanup_connector_credential_pair_task(
f"Cannot run deletion attempt - connector_credential_pair with Connector ID: "
f"{connector_id} and Credential ID: {credential_id} does not exist."
)

deletion_attempt_disallowed_reason = check_deletion_attempt_is_allowed(
connector_credential_pair=cc_pair, db_session=db_session
)
if deletion_attempt_disallowed_reason:
raise ValueError(deletion_attempt_disallowed_reason)

try:
deletion_attempt_disallowed_reason = check_deletion_attempt_is_allowed(
connector_credential_pair=cc_pair, db_session=db_session
)
if deletion_attempt_disallowed_reason:
raise ValueError(deletion_attempt_disallowed_reason)

# The bulk of the work is in here, updates Postgres and Vespa
curr_ind_name, sec_ind_name = get_both_index_names(db_session)
document_index = get_default_document_index(
Expand All @@ -127,10 +129,15 @@ def cleanup_connector_credential_pair_task(
document_index=document_index,
cc_pair=cc_pair,
)

except Exception as e:
stack_trace = traceback.format_exc()
error_message = f"Error: {str(e)}\n\nStack Trace:\n{stack_trace}"
add_deletion_failure_message(db_session, cc_pair.id, error_message)
task_logger.exception(
f"Failed to run connector_deletion. "
f"connector_id={connector_id} credential_id={credential_id}"
f"connector_id={connector_id} credential_id={credential_id}\n"
f"Stack Trace:\n{stack_trace}"
)
raise e

Expand Down Expand Up @@ -410,6 +417,7 @@ def check_for_cc_pair_deletion_task() -> None:
task_logger.info(
f"Deleting the {cc_pair.name} connector credential pair"
)

cleanup_connector_credential_pair_task.apply_async(
kwargs=dict(
connector_id=cc_pair.connector.id,
Expand Down
12 changes: 12 additions & 0 deletions backend/danswer/db/connector_credential_pair.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ def get_connector_credential_pairs(
return list(results.all())


def add_deletion_failure_message(
db_session: Session,
cc_pair_id: int,
failure_message: str,
) -> None:
cc_pair = get_connector_credential_pair_from_id(cc_pair_id, db_session)
if not cc_pair:
return
cc_pair.deletion_failure_message = failure_message
db_session.commit()


def get_cc_pair_groups_for_ids(
db_session: Session,
cc_pair_ids: list[int],
Expand Down
3 changes: 3 additions & 0 deletions backend/danswer/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,9 @@ class ConnectorCredentialPair(Base):
connector_id: Mapped[int] = mapped_column(
ForeignKey("connector.id"), primary_key=True
)

deletion_failure_message: Mapped[str | None] = mapped_column(String, nullable=True)

credential_id: Mapped[int] = mapped_column(
ForeignKey("credential.id"), primary_key=True
)
Expand Down
2 changes: 2 additions & 0 deletions backend/danswer/server/documents/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ class CCPairFullInfo(BaseModel):
latest_deletion_attempt: DeletionAttemptSnapshot | None
is_public: bool
is_editable_for_current_user: bool
deletion_failure_message: str | None

@classmethod
def from_models(
Expand Down Expand Up @@ -262,6 +263,7 @@ def from_models(
latest_deletion_attempt=latest_deletion_attempt,
is_public=cc_pair_model.is_public,
is_editable_for_current_user=is_editable_for_current_user,
deletion_failure_message=cc_pair_model.deletion_failure_message,
)


Expand Down
25 changes: 25 additions & 0 deletions web/src/app/admin/connector/[ccPairId]/DeletionErrorStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { FiInfo } from "react-icons/fi";

export default function DeletionErrorStatus({
deletion_failure_message,
}: {
deletion_failure_message: string;
}) {
return (
<div className="mt-2 rounded-md border border-error-300 bg-error-50 p-4 text-error-600 max-w-3xl">
<div className="flex items-center">
<h3 className="text-base font-medium">Deletion Error</h3>
<div className="ml-2 relative group">
<FiInfo className="h-4 w-4 text-error-600 cursor-help" />
<div className="absolute z-10 w-64 p-2 mt-2 text-sm bg-white rounded-md shadow-lg opacity-0 group-hover:opacity-100 transition-opacity duration-300 border border-gray-200">
This error occurred while attempting to delete the connector. You
may re-attempt a deletion by clicking the &quot;Delete&quot; button.
</div>
</div>
</div>
<div className="mt-2 text-sm">
<p>{deletion_failure_message}</p>
</div>
</div>
);
}
12 changes: 12 additions & 0 deletions web/src/app/admin/connector/[ccPairId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { useEffect, useRef, useState } from "react";
import { CheckmarkIcon, EditIcon, XIcon } from "@/components/icons/icons";
import { usePopup } from "@/components/admin/connectors/Popup";
import { updateConnectorCredentialPairName } from "@/lib/connector";
import DeletionErrorStatus from "./DeletionErrorStatus";

// since the uploaded files are cleaned up after some period of time
// re-indexing will not work for the file connector. Also, it would not
Expand Down Expand Up @@ -184,6 +185,17 @@ function Main({ ccPairId }: { ccPairId: number }) {
: "This connector belongs to groups where you don't have curator permissions, so it's not editable."}
</div>
)}

{ccPair.deletion_failure_message &&
ccPair.status === ConnectorCredentialPairStatus.DELETING && (
<>
<div className="mt-6" />
<DeletionErrorStatus
deletion_failure_message={ccPair.deletion_failure_message}
/>
</>
)}

{credentialTemplates[ccPair.connector.source] &&
ccPair.is_editable_for_current_user && (
<>
Expand Down
1 change: 1 addition & 0 deletions web/src/app/admin/connector/[ccPairId]/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface CCPairFullInfo {
latest_deletion_attempt: DeletionAttemptSnapshot | null;
is_public: boolean;
is_editable_for_current_user: boolean;
deletion_failure_message: string | null;
}

export interface PaginatedIndexAttempts {
Expand Down
12 changes: 12 additions & 0 deletions web/tailwind-themes/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ module.exports = {

input: "#ffffff",

// Error colors
"error-50": "#fef2f2",
"error-100": "#fee2e2",
"error-200": "#fecaca",
"error-300": "#fca5a5",
"error-400": "#f87171",
"error-500": "#ef4444",
"error-600": "#dc2626",
"error-700": "#b91c1c",
"error-800": "#991b1b",
"error-900": "#7f1d1d",

background: "#fafafa", // 50
"background-100": "#f5f5f5", // neutral-100
"background-125": "#F1F2F4", // gray-125
Expand Down
Loading