Conversation
Inspect Google REST API error payloads in GmailProvider.sendMessage(): disambiguate HTTP 400 malformed payloads from invalid recipients to prevent false-positive suppression; disambiguate HTTP 403 between daily sending quotas, abuse/spam policies, and genuine auth failures without false reauth mutation; align HTTP 429 tokens to PROVIDER_RATE_LIMITED to activate mailbox cooldown. Closes #33.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The forensic audit (Issue #24, PR #31) identified three critical error-mapping defects in
apps/api/src/services/google/gmail.provider.ts:INVALID_RECIPIENT, triggering false-positive permanent suppression of valid contacts asHARD_BOUNCE.MAILBOX_REAUTH_REQUIRED, mutatingGoogleConnectionModelandEmailAccountModeltoreauth_requiredand falsely instructing users to reconnect their OAuth authorization when their credentials were valid.SENDER_RATE_LIMITEDwithrate_limit, while downstreamEmailService.send()checked forPROVIDER_RATE_LIMITEDandprovider_rate_limited, silently bypassing mailbox rate-limit cooldown.Root Cause
GmailProvider.sendMessage()inspected only HTTP status codes (400,401/403,429) without examining Google API response error structures (body.error.message,body.error.status,body.error.errors[].reason).GmailProvider(SENDER_RATE_LIMITED) andEmailService.send()(PROVIDER_RATE_LIMITED).classifyEmailFailure()lacked dedicated classification cases for provider payload formatting errors (MALFORMED_PAYLOAD) and provider anti-abuse blocks (POLICY_BLOCKED).Changes
apps/api/src/services/email/types.ts:'MALFORMED_PAYLOAD','POLICY_BLOCKED', and'QUOTA_EXCEEDED'toEmailProviderErrorShape['code'].apps/api/src/services/google/gmail.provider.ts:INVALID_RECIPIENT; otherwise throwsMALFORMED_PAYLOAD(classification: 'malformed_payload').dailyLimitExceeded,userRateLimitExceeded, quota message): throwsPROVIDER_RATE_LIMITEDwith parsedRetry-Afterdelay without mutating connection status.abuse,spam,policyRejection, bulk sending messages): throwsPOLICY_BLOCKEDwithout mutating connection status.GoogleConnectionModeltoreauth_requiredand throwsMAILBOX_REAUTH_REQUIRED.PROVIDER_RATE_LIMITED(classification: 'provider_rate_limited') with parsedRetry-Afterdelay.apps/api/src/services/email/email.service.ts:classifyEmailFailure():MALFORMED_PAYLOADtoEmailFailureCategory.INTERNAL(isHardBounce: false, non-retryable).POLICY_BLOCKEDtoEmailFailureCategory.POLICY(isHardBounce: false, non-retryable).PROVIDER_RATE_LIMITED/QUOTA_EXCEEDEDtoEmailFailureCategory.RATE_LIMIT(isHardBounce: false, retryable).send():PROVIDER_RATE_LIMITED,SENDER_RATE_LIMITED,QUOTA_EXCEEDED, andRATE_LIMITfailures.MALFORMED_PAYLOADfrom triggering contact suppression.apps/api/src/middleware/error-handler.ts:POLICY_BLOCKEDto HTTP 403 status map.apps/api/src/services/google/gmail-error-normalization.test.ts(10 tests covering 400 payload vs recipient, 403 quota vs abuse vs auth, 429 rate limit, and suppression prevention).apps/api/src/services/email/outbound-provider-rejection-audit.test.tsFinding 2 tests to verify remediated behavior.Safety Impact
Tests
pnpm --filter @leadforge/schema check-types: Clean (0 errors)pnpm --filter api check-types: Clean (0 errors)pnpm --filter api exec vitest run src/services/email/ src/services/google/: 6 test files passed (51 passed)Verification
MALFORMED_PAYLOAD, categorized asINTERNAL, and do not suppress contacts.INVALID_RECIPIENTand trigger suppression.PROVIDER_RATE_LIMITED, do not set connectionreauth_required, and activate mailbox cooldown.POLICY_BLOCKEDand do not set connectionreauth_required.MAILBOX_REAUTH_REQUIREDand set connectionreauth_required.PROVIDER_RATE_LIMITEDand trigger mailbox cooldown.Scope
Related Issue