diff --git a/connectors/src/admin/cli.ts b/connectors/src/admin/cli.ts index b382cf438a4f..bb193b771586 100644 --- a/connectors/src/admin/cli.ts +++ b/connectors/src/admin/cli.ts @@ -1,3 +1,4 @@ +import { isConnectorError } from "@dust-tt/types"; import parseArgs from "minimist"; import PQueue from "p-queue"; import readline from "readline"; @@ -130,6 +131,18 @@ const connectors = async (command: string, args: parseArgs.ParsedArgs) => { return; } + case "set-error": { + if (!args.error) { + throw new Error("Missing --error argument"); + } + if (!isConnectorError(args.error)) { + throw new Error(`Invalid error: ${args.error}`); + } + connector.errorType = args.error; + await connector.save(); + return; + } + case "restart": { await throwOnError( STOP_CONNECTOR_BY_TYPE[provider](connector.id.toString()) @@ -263,6 +276,7 @@ const notion = async (command: string, args: parseArgs.ParsedArgs) => { const connectors = await Connector.findAll({ where: { type: "notion", + errorType: null, }, }); for (const connector of connectors) { diff --git a/front/components/data_source/DataSourceSyncChip.tsx b/front/components/data_source/DataSourceSyncChip.tsx index e4d1f05f1b1a..48356e0c2cd0 100644 --- a/front/components/data_source/DataSourceSyncChip.tsx +++ b/front/components/data_source/DataSourceSyncChip.tsx @@ -1,7 +1,9 @@ import { Chip } from "@dust-tt/sparkle"; import type { ConnectorType } from "@dust-tt/types"; +import { assertNever } from "@dust-tt/types"; import { useEffect, useState } from "react"; +import { CONNECTOR_CONFIGURATIONS } from "@app/lib/connector_providers"; import { timeAgoFrom } from "@app/lib/utils"; export default function ConnectorSyncingChip({ @@ -19,8 +21,29 @@ export default function ConnectorSyncingChip({ if (connector.errorType) { return ( - Oops! It seems that our access to your account has been revoked. Please - re-authorize this Data Source to keep your data up to date on Dust. + {(() => { + switch (connector.errorType) { + case "oauth_token_revoked": + return ( + <> + Oops! It seems that our access to your account has been + revoked. Please re-authorize this Data Source to keep your + data up to date on Dust. + + ); + case "third_party_internal_error": + return ( + <> + We have ecountered an error talking to{" "} + {CONNECTOR_CONFIGURATIONS[connector.type].name}. We sent you + an email with more details to resolve the issue. + + ); + default: + assertNever(connector.errorType); + } + return <>; + })()} ); } else if (!connector.lastSyncSuccessfulTime) { diff --git a/types/src/front/lib/connectors_api.ts b/types/src/front/lib/connectors_api.ts index e85b281eecf4..ebab95f9b371 100644 --- a/types/src/front/lib/connectors_api.ts +++ b/types/src/front/lib/connectors_api.ts @@ -10,7 +10,15 @@ const { export type ConnectorsAPIResponse = Result; export type ConnectorSyncStatus = "succeeded" | "failed"; -export type ConnectorErrorType = "oauth_token_revoked"; +const CONNECTORS_ERROR_TYPES = [ + "oauth_token_revoked", + "third_party_internal_error", +] as const; + +export type ConnectorErrorType = (typeof CONNECTORS_ERROR_TYPES)[number]; +export function isConnectorError(val: string): val is ConnectorErrorType { + return (CONNECTORS_ERROR_TYPES as unknown as string[]).includes(val); +} export const CONNECTOR_PROVIDERS_USING_NANGO = [ "confluence",