Skip to content
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
7 changes: 6 additions & 1 deletion apps/web/utils/email/google.ts
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,11 @@ export class GmailProvider implements EmailProvider {
addLabelIds?: string[];
removeLabelIds?: string[];
}) {
return createFilter({ gmail: this.client, ...options });
return createFilter({
gmail: this.client,
...options,
logger: this.logger,
});
}

async createAutoArchiveFilter(options: {
Expand All @@ -869,6 +873,7 @@ export class GmailProvider implements EmailProvider {
gmail: this.client,
from: options.from,
gmailLabelId: options.gmailLabelId,
logger: this.logger,
});
}

Expand Down
40 changes: 39 additions & 1 deletion apps/web/utils/gmail/filter.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import type { gmail_v1 } from "@googleapis/gmail";
import { GmailLabel } from "@/utils/gmail/label";
import { extractErrorInfo, withGmailRetry } from "@/utils/gmail/retry";
import { SafeError } from "@/utils/error";
import type { Logger } from "@/utils/logger";

export async function createFilter(options: {
gmail: gmail_v1.Gmail;
from: string;
addLabelIds?: string[];
removeLabelIds?: string[];
logger: Logger;
}) {
const { gmail, from, addLabelIds, removeLabelIds } = options;
const { gmail, from, addLabelIds, removeLabelIds, logger } = options;

try {
return await withGmailRetry(() =>
Expand All @@ -25,6 +28,38 @@ export async function createFilter(options: {
);
} catch (error) {
if (isFilterExistsError(error)) return { status: 200 };

const errorInfo = extractErrorInfo(error);

logger.error("Failed to create Gmail filter", {
from,
addLabelIds,
removeLabelIds,
error,
});

// Check if it might be a filter limit issue
// Documentation says 400/403, but we've seen 500 in production
if (
errorInfo.status === 500 ||
errorInfo.status === 403 ||
errorInfo.status === 400
) {
try {
const filters = await getFiltersList({ gmail });
const filterCount = filters.data?.filter?.length ?? 0;
Comment thread
elie222 marked this conversation as resolved.
if (filterCount >= 990) {
throw new SafeError(
`Gmail filter limit reached (${filterCount}/1000 filters). Please delete some existing filters in Gmail settings.`,
);
}
} catch (limitCheckError) {
if (limitCheckError instanceof SafeError) throw limitCheckError;
// If limit check fails, just log and continue with original error
logger.warn("Failed to check filter count", { error: limitCheckError });
}
}

throw error;
}
}
Expand All @@ -33,17 +68,20 @@ export async function createAutoArchiveFilter({
gmail,
from,
gmailLabelId,
logger,
}: {
gmail: gmail_v1.Gmail;
from: string;
gmailLabelId?: string;
logger: Logger;
}) {
try {
return await createFilter({
gmail,
from,
removeLabelIds: [GmailLabel.INBOX],
addLabelIds: gmailLabelId ? [gmailLabelId] : undefined,
logger,
});
} catch (error) {
if (isFilterExistsError(error)) return { status: 200 };
Expand Down
Loading