Skip to content

fix: refactor i18n loadTranslations and set timeout to 3s #22633

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 1, 2025
Merged

Conversation

hbjORbj
Copy link
Contributor

@hbjORbj hbjORbj commented Jul 18, 2025

What does this PR do?

  • Add validations for locale and ns, and fallback to Engllish and common namespace
  • Add 3s max timeout as well (fetch gets aborted if not completed within 3s)

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • N/A - I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Please use the latest Vercel preview and test please 🙏.

Copy link
Contributor

coderabbitai bot commented Jul 18, 2025

Walkthrough

A new asynchronous utility function, fetchWithTimeout, has been added to perform HTTP fetch requests with a specified timeout using an AbortController. The translation loading logic in the server-side i18n module has been refactored: the fallback to English translations on failure is removed, and explicit lists of supported locales and namespaces are enforced. The loadTranslations function now normalizes and validates locales and namespaces, defaults to "en" or "common" if unsupported, and uses the new fetchWithTimeout with a 3-second timeout for translation fetching. On fetch failure, it logs an error and returns an empty object, maintaining the caching mechanism for successful fetches. Additionally, several test files were updated to mock the @calcom/lib/server/i18n module by providing an asynchronous stub getTranslation function that returns a translation function echoing the input key and carrying locale and namespace properties.

Estimated code review effort

3 (90–240 minutes)

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/features/ee/billing/credit-service.test.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-playwright".

(The package "eslint-plugin-playwright" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-playwright@latest --save-dev

The plugin "eslint-plugin-playwright" was referenced from the config file in ".eslintrc.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

packages/features/ee/organizations/lib/server/createOrganizationFromOnboarding.test.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-playwright".

(The package "eslint-plugin-playwright" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-playwright@latest --save-dev

The plugin "eslint-plugin-playwright" was referenced from the config file in ".eslintrc.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

packages/features/ee/workflows/lib/reminders/reminderScheduler.test.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-playwright".

(The package "eslint-plugin-playwright" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-playwright@latest --save-dev

The plugin "eslint-plugin-playwright" was referenced from the config file in ".eslintrc.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

  • 4 others

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3ca129 and 3ed8ff8.

📒 Files selected for processing (7)
  • apps/web/test/lib/handleChildrenEventTypes.test.ts (1 hunks)
  • packages/features/ee/billing/credit-service.test.ts (1 hunks)
  • packages/features/ee/organizations/lib/server/createOrganizationFromOnboarding.test.ts (1 hunks)
  • packages/features/ee/workflows/lib/reminders/reminderScheduler.test.ts (1 hunks)
  • packages/features/ee/workflows/lib/test/compareReminderBodyToTemplate.test.ts (2 hunks)
  • packages/lib/server/repository/user.test.ts (1 hunks)
  • packages/lib/server/service/userCreationService.test.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • packages/features/ee/workflows/lib/reminders/reminderScheduler.test.ts
  • packages/features/ee/organizations/lib/server/createOrganizationFromOnboarding.test.ts
  • packages/features/ee/billing/credit-service.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/features/ee/workflows/lib/test/compareReminderBodyToTemplate.test.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Security Check
🔇 Additional comments (3)
apps/web/test/lib/handleChildrenEventTypes.test.ts (1)

27-36: LGTM! Mock properly reflects the new async i18n behavior.

The mock correctly implements the new async signature for getTranslation, accepting locale and namespace parameters and returning a translation function with attached properties. This aligns with the i18n refactoring described in the PR.

packages/lib/server/service/userCreationService.test.ts (1)

12-21: LGTM! Consistent mock implementation.

The mock implementation is identical to other test files and correctly simulates the new async getTranslation behavior. The function signature and returned value structure are appropriate for testing purposes.

packages/lib/server/repository/user.test.ts (1)

10-19: LGTM! Excellent consistency across test files.

The mock implementation matches the pattern used in other test files, properly implementing the new async getTranslation signature. The coordinated updates across multiple test files demonstrate good maintenance practices.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@graphite-app graphite-app bot requested a review from a team July 18, 2025 18:25
@keithwillcode keithwillcode added core area: core, team members only foundation labels Jul 18, 2025
@hbjORbj hbjORbj changed the title fix: i18n fix fix: refactor i18n loadTranslations and set timeout to 3s Jul 18, 2025
Copy link

vercel bot commented Jul 18, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
cal ⬜️ Ignored (Inspect) Jul 21, 2025 5:55am
cal-eu ⬜️ Ignored (Inspect) Jul 21, 2025 5:55am

@dosubot dosubot bot added the i18n area: i18n, translations label Jul 18, 2025
Copy link

delve-auditor bot commented Jul 18, 2025

No security or compliance issues detected. Reviewed everything up to 1a89321.

Security Overview
  • 🔎 Scanned files: 9 changed file(s)
Detected Code Changes
Change Type Relevant files
Enhancement ► fetchWithTimeout.ts
    Add new fetch utility with timeout functionality
Bug Fix ► handleChildrenEventTypes.test.ts
    Fix translation mock
► credit-service.test.ts
    Update translation mock and remove redundant test
► createOrganizationFromOnboarding.test.ts
    Add missing translation mock
► reminderScheduler.test.ts
    Add missing translation mock
► compareReminderBodyToTemplate.test.ts
    Add translation mock
► i18n.ts
    Improve translation handling and error management

Reply to this PR with @delve-auditor followed by a description of what change you want and we'll auto-submit a change to this PR to implement it.

Copy link

delve-auditor bot commented Jul 18, 2025

No security or compliance issues detected. Reviewed everything up to 85edbca.

Security Overview
  • 🔎 Scanned files: 2 changed file(s)
Detected Code Changes
Change Type Relevant files
Enhancement ► fetchWithTimeout.ts
    Add fetch with timeout utility
► getUserAvailability.ts
    Simplify booking and duration limits parsing
► i18n.ts
    Add timeout to translation fetching
Refactor ► PermissionGuard.ts
    Remove third party token handling
► slots.service.ts
    Consolidate slots fetching logic
► ApiAuthStrategy.ts
    Simplify authentication logic
Configuration changes ► slots-input.pipe.ts
    Update slots input validation
► get-slots.input.ts
    Add routing parameters

Reply to this PR with @delve-auditor followed by a description of what change you want and we'll auto-submit a change to this PR to implement it.

Copy link

graphite-app bot commented Jul 18, 2025

Graphite Automations

"Add consumer team as reviewer" took an action on this PR • (07/18/25)

1 reviewer was added to this PR based on Keith Williams's automation.

zomars
zomars previously approved these changes Jul 18, 2025
Copy link
Member

@zomars zomars left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code LGTM. Is there any reason why timeouts are happening tho?

const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there not just a value you can send in fetch instead of needing to set a timeout?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope :( I searched something like that but there wasn't. Lmk if you know something!

Copy link
Contributor

github-actions bot commented Jul 18, 2025

E2E results are ready!

zomars
zomars previously approved these changes Jul 18, 2025
@hbjORbj
Copy link
Contributor Author

hbjORbj commented Jul 18, 2025

Code LGTM. Is there any reason why timeouts are happening tho? @zomars

We didn't validate locale or namespace before making a fetch request, and this request was not being resolved for 60s (the default max timeout time set by Vercel). Now that we validate locale and namespace with fallback values to english and common, this should no longer happen

@hbjORbj hbjORbj marked this pull request as ready for review July 19, 2025 10:01
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/lib/server/i18n.ts (1)

11-11: Address the hardcoded namespace list as previously discussed.

Based on past review comments, this hardcoded list creates maintenance overhead as it's duplicated elsewhere in the codebase.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 815dde4 and be977e3.

📒 Files selected for processing (5)
  • packages/features/ee/billing/credit-service.test.ts (1 hunks)
  • packages/features/ee/organizations/lib/server/createOrganizationFromOnboarding.test.ts (1 hunks)
  • packages/features/ee/workflows/lib/reminders/reminderScheduler.test.ts (1 hunks)
  • packages/features/ee/workflows/lib/test/compareReminderBodyToTemplate.test.ts (2 hunks)
  • packages/lib/server/i18n.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • packages/features/ee/organizations/lib/server/createOrganizationFromOnboarding.test.ts
  • packages/features/ee/workflows/lib/reminders/reminderScheduler.test.ts
  • packages/features/ee/billing/credit-service.test.ts
🧰 Additional context used
🧠 Learnings (1)
packages/lib/server/i18n.ts (1)
Learnt from: bandhan-majumder
PR: calcom/cal.com#22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.201Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
🧬 Code Graph Analysis (1)
packages/lib/server/i18n.ts (3)
packages/config/next-i18next.config.d.ts (1)
  • i18n (2-5)
packages/lib/constants.ts (1)
  • WEBAPP_URL (12-18)
packages/lib/fetchWithTimeout.ts (1)
  • fetchWithTimeout (1-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Security Check
🔇 Additional comments (6)
packages/features/ee/workflows/lib/test/compareReminderBodyToTemplate.test.ts (2)

2-2: LGTM: Added vitest import for mocking.

The addition of vi import enables proper mocking functionality for the test suite.


13-17: LGTM: Appropriate mocking of i18n module.

The mock implementation correctly stubs the getTranslation function to return the input key, which is appropriate for testing purposes and isolates tests from the actual i18n implementation changes.

packages/lib/server/i18n.ts (4)

3-3: LGTM: Added i18n config import for locale validation.

The import enables proper validation of locales against the supported list from the configuration.


6-8: LGTM: Added necessary imports for timeout and logging.

The new imports support the enhanced error handling and timeout functionality.


19-22: LGTM: Robust validation and normalization logic.

The implementation correctly:

  • Normalizes "zh" to "zh-CN" for proper locale handling
  • Validates locales against the supported list from configuration
  • Validates namespaces against the supported list
  • Falls back to safe defaults ("en" locale, "common" namespace)

This addresses the core issue mentioned in PR objectives where invalid parameters could cause fetch requests to hang.


38-46: LGTM: Improved error handling with proper logging.

The error handling correctly:

  • Logs fetch failures for debugging
  • Returns an empty object instead of throwing
  • Maintains the caching mechanism for successful responses

This is a significant improvement over the previous fallback approach, as it prevents cascading failures and provides clearer error visibility.

@hbjORbj
Copy link
Contributor Author

hbjORbj commented Jul 25, 2025

@keithwillcode Keith, can you review it once more?

@hbjORbj hbjORbj merged commit 6ff20b9 into main Aug 1, 2025
43 checks passed
@hbjORbj hbjORbj deleted the fix/i18n-fix branch August 1, 2025 13:30
emrysal added a commit that referenced this pull request Aug 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core area: core, team members only foundation i18n area: i18n, translations ready-for-e2e 💻 refactor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants