Your Google Calendar sync breaks at 3am. The logs say "403 Forbidden." That's it. No context. No reason. Just access denied.
Is the OAuth token expired? Did the user revoke access? Is there a scope mismatch? Rate limit? You're left guessing, checking every integration point, reviewing auth flows, debugging in the dark.
This week we shipped a small fix that makes those errors actually useful.
Google Already Told Us Why
When Google's Calendar API rejects a request with 401 or 403, it includes a reason field in the error response. Things like:
• authError — OAuth token expired or invalid
• insufficientPermissions — Missing required scopes
• accessNotConfigured — Calendar API not enabled in GCP project
• userRateLimitExceeded — Hit per-user quota
We were catching the exception, logging the status code, and swallowing the reason. The information was right there in Google's response—we just weren't using it.
The Fix
Now when Sabine hits a Google Calendar auth error, we parse the reason field from the JSON error response and include it in our exception message and logs.
Instead of:
GCalAuthError: 403 Forbidden
You get:
GCalAuthError: 403 Forbidden (reason: insufficientPermissions)
That one extra field tells you exactly what's wrong. No detective work. No trial-and-error re-auth flows. Just actionable signal.
Why This Matters
Calendar sync is fragile by nature. OAuth tokens expire. Users revoke access. API quotas get hit. Scopes change. Every integration has failure modes.
When sync breaks, you need fast diagnosis. The difference between "403 Forbidden" and "403 Forbidden (authError)" is the difference between spending 10 minutes checking OAuth token refresh logic versus immediately knowing the token is stale.
This is defensive engineering. Make errors informative. Surface what the API already told you. Reduce debugging time from hours to minutes.
What's Next
This pattern should extend to every external API we integrate. Microsoft Graph, Outlook, Slack—they all return structured error reasons. We should be surfacing them consistently.
We're also building better observability around calendar sync health. When a user's calendar feed goes stale, we want to know immediately—and know why. Reason codes are the first step. Next is proactive monitoring and user-facing status indicators.
Good errors are infrastructure. They compound. Every auth failure that includes a reason code is one less support ticket, one less hour of debugging, one less frustrated engineer.