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",