From 3b321f4ba12579ee95635565f1aac6fab2f3e3ee Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Wed, 17 Jun 2026 12:37:37 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Ignore=20expected=20WhatsApp=20w?= =?UTF-8?q?ebhook=20errors=20(#2527)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added a viewer ORPC Sentry filter for expected production WhatsApp webhook validation failures. - Kept invalid webhook secret, signature, and payload responses flowing back to callers without reporting them to Sentry. --- .../config/src/orpc/viewer/middlewares.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/config/src/orpc/viewer/middlewares.ts b/packages/config/src/orpc/viewer/middlewares.ts index 5359802d5..a8ccbfc1e 100644 --- a/packages/config/src/orpc/viewer/middlewares.ts +++ b/packages/config/src/orpc/viewer/middlewares.ts @@ -11,6 +11,21 @@ const webhookUrlPaths = [ "billingRouter/webhook", ]; +const expectedWhatsAppWebhookValidationErrors = [ + { + code: "UNAUTHORIZED", + message: "Invalid WhatsApp webhook secret", + }, + { + code: "UNAUTHORIZED", + message: "Invalid WhatsApp webhook signature", + }, + { + code: "BAD_REQUEST", + message: "Invalid WhatsApp webhook payload", + }, +]; + const sentryMiddleware = os.middleware(async ({ next, path }) => { try { return await next(); @@ -34,6 +49,8 @@ const sentryMiddleware = os.middleware(async ({ next, path }) => { }); const isUnknownError = (error: unknown, path: string) => { + if (isExpectedWhatsAppWebhookValidationError(error, path)) return false; + if ( error instanceof ORPCError && !error.code?.includes("INTERNAL_SERVER_ERROR") && @@ -44,6 +61,18 @@ const isUnknownError = (error: unknown, path: string) => { return true; }; +const isExpectedWhatsAppWebhookValidationError = ( + error: unknown, + path: string, +) => + path === "chatWhatsAppRouter/productionWebhookProcedure" && + error instanceof ORPCError && + expectedWhatsAppWebhookValidationErrors.some( + (expectedError) => + error.code === expectedError.code && + error.message === expectedError.message, + ); + const requireAuth = oo.spec( os.middleware(async ({ next, context }) => { const user = await context.authenticate();