Skip to content

fix: handle non-numeric error codes from Microsoft Graph in OAuth callback#580

Merged
andris9 merged 1 commit intopostalsys:masterfrom
bgeihsgt:fix/handle-non-numeric-graph-error-codes
Feb 26, 2026
Merged

fix: handle non-numeric error codes from Microsoft Graph in OAuth callback#580
andris9 merged 1 commit intopostalsys:masterfrom
bgeihsgt:fix/handle-non-numeric-graph-error-codes

Conversation

@bgeihsgt
Copy link
Contributor

Problem

When Microsoft Graph returns an error during OAuth profile fetch (e.g. HTTP 429 throttling), the JSON body contains a string error.code (e.g. "TooManyPendingRequests") rather than a numeric code. Passing this directly to Boom.boomify() as statusCode causes an AssertError crash because Boom requires a numeric value >= 400.

AssertError: First argument must be a number (400+): TooManyPendingRequests
  at internals.initialize (/emailengine/node_modules/@hapi/boom/lib/index.js:404:10)
  at exports.boomify (/emailengine/node_modules/@hapi/boom/lib/index.js:126:26)
  at handler (/emailengine/workers/api.js:2242:50)

Gmail is unaffected because Google APIs return numeric error.code values in their JSON error bodies (e.g. 403, 404). This bug manifests with Microsoft Graph (and potentially Mail.ru) because Microsoft uses string error codes like "TooManyPendingRequests", "TooManyRequests", "BadRequest", etc.

Fix

All three instances of the pattern in workers/api.js (Gmail, Outlook, and Mail.ru catch blocks) now check whether response.error.code is a valid numeric HTTP status code (number >= 400) before using it. If it's not numeric, the code falls back to the HTTP status code already captured on the error object (err.statusCode or err.oauthRequest.status), defaulting to 500 if neither is available.

This preserves existing behavior for Google APIs while correctly handling string error codes from Microsoft Graph and other providers.

Steps to Reproduce

  1. Configure an Outlook OAuth2 app with Graph API base scopes
  2. Initiate an OAuth connection for a mailbox that is being rate-limited by Microsoft
  3. The /oauth callback handler crashes with AssertError instead of returning a 429

@CLAassistant
Copy link

CLAassistant commented Feb 25, 2026

CLA assistant check
All committers have signed the CLA.

…lback

Microsoft Graph API returns string error codes (e.g. "TooManyPendingRequests")
in JSON error responses, unlike Google APIs which return numeric codes. Passing
these strings to Boom.boomify() as statusCode causes an AssertError crash since
Boom requires a numeric value >= 400.

Extract resolveOAuthErrorStatus() helper into lib/tools.js to check if
response.error.code is a valid numeric HTTP status code before using it,
falling back to the HTTP status already captured on err.statusCode or
err.oauthRequest.status.
@bgeihsgt bgeihsgt force-pushed the fix/handle-non-numeric-graph-error-codes branch from 5a2f3ca to 898fc65 Compare February 25, 2026 23:39
@andris9
Copy link
Collaborator

andris9 commented Feb 26, 2026

Thanks! Next time, you can just send the stack trace, no need to come up with an actual fix 🙂

@andris9 andris9 merged commit 89fd9f7 into postalsys:master Feb 26, 2026
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants